Spring----AOP

1.Advice
分为四种:
Before Advice,需要extends BeforeAdvice。重写void before(Method m, Object[] args, Object target) throws Throwable;

After advice,需要extends Advice。重写void afterReturning(Object returnValue, Method m, Object[] args, Object target) throws Throwable;
注意After advice中可以访问代理方法的返回值,但不能修改

环绕Advice
例子:

public interface MethodInterceptor extends Interceptor {
      Object invoke(MethodInvocation invocation) throws Throwable;
}
public class DebugInterceptor implements MethodInterceptor {

    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("Before: invocation=[" + invocation + "]");  //(1)
        Object rval = invocation.proceed();
        System.out.println("Invocation returned");  //(2)
        return rval;
    }
}

invocation.proceed()方法运行指向连接点的拦截器链并返回proceed()的结果

Throws Advice
是一个空接口,起标识作用
实现方法afterThrowing([Method], [args], [target], Throwable)。
也可以为afterThrowing( Throwable)

2.advisor
advisor会具有advice的功能并过滤所不需要代理的方法,只代理标识的方法

<!-- 配置advisor -->
    <!-- 作用:筛选要拦截的方法 -->
    <bean name="advisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
        <!-- 注入advice -->
        <property name="advice" ref="beforeAdvice"></property>
        <!-- 注入需要被拦截的目标对象中的方法 -->
        <property name="patterns">
            <list>
                <value>.*delete</value>
                <value>.*update</value>
            </list>
        </property>
    </bean>

3.AutoProxy
使用自动代理的时候需要注意的方面:
1.当前的配置里面一定要有 一个advisor的配置
2.不需要向自动代理类中注入任何信息
3.不管目标对象是否实现了一个或多接口,自动代理的方式都能够为它产生代理对象.
4,如果目标对象是没有实现接口的类,那么将自动使用CGlib代理对象
5.从spring容器中拿代理对象的时候,需要通过目标对象的
名字来拿。
配置:

<bean name="proxy"  class="org.springframework.aop.framework.autoproxy.DefaultAdvisorAutoProxyCreator">
    </bean>

4.AutoProxyByName
使用自动代理byName的方式的时候需要注意的方面:
1.当前的配置里有没有advisor的配置都可以
2.需要向自动代理类中注入目标对象的名字和advisor或者advice
3.不管目标对象是否实现了一个或多接口,自动代理的方式都能够为它产生代理对象。
4,如果目标对象是没有实现接口的类,那么将自动使用CGlib代理对象
5.从spring容器中拿代理对象的时候,需要通过目标对象的名字来拿。
配置:

<!-- 这里使用自动代理的方式 autoproxybyname -->
    <bean name="proxy" class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
        <!-- 注入需要被代理的对象名字 -->
        <property name="beanNames">
            <list>
                <value>target2</value>
                <value>target3</value>
            </list>
        </property>

        <!-- 注入advice或者advisor -->
        <property name="interceptorNames">
            <list>
                <value>beforeAdvice</value>
            </list>
        </property>
    </bean>

6.aop:config标签
需要更改约束

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-3.2.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.2.xsd
           http://www.springframework.org/schema/aop
           http://www.springframework.org/schema/aop/spring-aop-3.2.xsd">

例子:

 <!-- 配置aop的代理 -->
       <aop:config>
        <!-- 定义一个切入点 并给切入点起名为myPointCut -->
        <!-- 切入点是一组连接点的集合 -->
        <aop:pointcut expression="execution(public * com.ma.aop.before.MathImp.*(..))" id="myPointCut"/>

        <!-- 定义哪一个advice在哪一个切入点上面起作用 -->
        <aop:advisor advice-ref="beforeAdivce" pointcut-ref="myPointCut" />
        </aop:config>

常见切入点表达式例子
1)任意公共方法的执行:
execution(public * *(..))
2)任何一个以“set”开始的方法的执行:
execution(* set*(..))
3)AccountService 接口的任意方法的执行:
execution(* com.briup.service.AccountService.*(..))
4)定义在service包里的任意方法的执行:
execution(* com.briup.service..(..))
5)定义在service包或者子包里的任意方法的执行:
execution(* com.briup.service...(..))
6)在service包里的任意连接点(在Spring AOP中只是方法执行)
within(com.xyz.service.*)
7)在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) : within(com.xyz.service..*)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章