Spring AOP 代理

Spring AOP 代理

1. Spring AOP 增强类型

AOP 联盟为通知 Advice 定义了 org.aopalliance.aop.Interface.Advice

Spring 按照通知 Advice 在目标类方法的连接点位置,可以分为 5 类

  • 前置通知:org.springframework.aop.MethodBeforeAdvice

    在目标方法执行前实施增强

  • 后置通知:ogr.springframework.aop.AfterReturningAdvice

    在目标方法执行后实施增强

  • 环绕通知:ogr.aopalliance.intercept.MethodInterceptor

    在目标方法执行前后实施增强

  • 异常抛出通知:org.springframework.aop.ThrowsAdvice

    在方法抛出异常后实施增强

  • 引介通知:org.springframework.aop.IntroductionInterceptor

    在目标类中添加一些新的方法和属性(Spring 中不支持,只支持对方法增强)


2. Spring AOP 切面类型

  • Advisor:代表一般切面,Advice 本身就是一个切面,对目标类所有方法进行拦截
  • PointcutAdvisor:代表具有切点的切面,可以指定拦截目标类哪些方法(实现时需要配置切面信息,即类中要增强的方法设置bean)
  • IntroductionAdvisor:代表引介切面,针对引介通知而使用切面(不要求掌握)

3. Advisor 切面案例 (xml 配置)

ProxyFactoryBean 常用可配置属性:

  • target:代理的目标对象

  • proxyInterfaces:代理要实现的接口

    如果多个接口可以使用以下格式赋值:

    
      xxx
      ...
    
    
  • proxyTargetClass:是否对类代理而不是接口,设置为 true 时,使用 CGLib 代理

  • interceptorNames:需要织入目标的 Advice

  • singleton:返回代理是否为单实例,默认为单例

  • optimize:当设置为 true 时,强制使用 CGLib(默认为 JDK 动态代理)

举个例子:

applicationContext.xml









    
    
    
    
    
    
    
    
    

通知类:

public class MyBeforeAdvice implements MethodBeforeAdvice {
    @Override
    public void before(Method method, Object[] objects, Object o) throws Throwable {
        System.out.println("前置增强========");
    }
}

4. 演示(Advisor 方式)

首先要使用 AOP,我们需要导入两个包:


    aopalliance
    aopalliance
    1.0


    org.springframework
    spring-aop
    4.2.4.RELEASE

然后定义接口和实现类,再定义一个通知类(如前置通知),然后我们在 xml 文件中配置目标类和通知类,利用 Spring AOP 产生代理(通过bean配置),具体可参考上述例子,使用注解的方式在测试类中导入增强后的 bean:studentDaoProxy。

具体代码:SpringDemo3.demo1()


5. PointcutAdvisor 切点切面

使用普通 Advice 作为切面,将对目标类所有方法进行拦截,不够灵活,在实际开发中常采用带有切点的切面。

常用 PointcutAdvisor 实现类

  • DefaultPointcutAdvisor 最常用的切面类型,它可以通过任意 PointcutAdvice 组合定义切面
  • JdkRegexpMethodPointcut 构造正则表达式切点

这里以 JdkRegexpMethodPointcut 为例:

applicationContext.xml









    
    
    
    




    
    
    
    

通知类:

public class MyAroundAdvice implements MethodInterceptor{


    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        System.out.println("环绕前增强...");

        // 执行目标方法
        Object obj = methodInvocation.proceed();

        System.out.println("环绕后增强...");

        return obj;
    }
}

具体代码:SpringDemo4.demo1()


6. 自动创建代理

前面的案例中,每个代理都是通过 ProxyFactoryBean 织入切面代理,在实际开发中,非常多的 Bean 每个都配置 ProxyFactoryBean 开发维护量巨大。

解决方案:自动创建代理。

自动创建代理的三种方式:

  • BeanNameAutoProxyCreator 根据 Bean 名称创建代理
  • DefaultAdvisorAutoProxyCreator 根据 Advisor 本身包含信息创建代理
  • AnnotationAwareAspectJAutoProxyCreator 基于 Bean 中的 AspectJ 注解进行自动代理(最主要方式)

7. BeanNameAutoProxyCreator 举例

对所有以 Dao 结尾 Bean 所有方法使用代理:











    
    


具体代码:SpringDemo5.demo1()


8. DefaultAdvisorAutoProxyCreator 举例

配置环绕代理案例:











    
    




具体代码:SpringDemo6.demo1()

你可能感兴趣的:(Spring AOP 代理)