Spring AOP原理

1.动态代理技术

1.JDK动态代理

基于Proxy类的#newInstance( )方法来获取目标对象的代理对象,JDK的动态代理必须基于接口实现,因为Java语言不支持多继承,但是支持多实现。
实现机制:

     1. 编写生成类实现`InvocationHandler接口`,覆盖invoke方法,实现切面逻辑。
     1. 通过Proxy的#newInstance( )静态方法来获取代理对象。

2.Cglib动态代理

Cglib是一个第三方代码生成库,是对ASM字节码技术的二次封装,在运行时动态生成代理对象,它的特点是基于子类继承的关系来实现。
特点:基于子类的继承、无法对final修饰的类和方法进行代理、效率高、额外引入Jar包。
实现机制:

     1. 编写生成类实现`MethodInterceptor接口`,覆盖intercept方法,实现切面逻辑。
     1. new一个Enhancer类来实现父子类的委托。
     1. 将实现了MethodInterceptor的类作为入参放入Enhancer的callbacks属性里。
     1. 通过enhancer对象的#create( )方法得到代理对象。

3.ASM字节码技术

ASM是一个操纵字节码的工具框架,ASM可以直接生成二进制的class文件,可以对class文件做修改。
实现机理:ASM通过访问者模式,将文件的内容从头到尾扫描,每当扫描到特定的内容标识就会回调对应的逻辑处理方法,基于此可以实现对源文件的增强,来实现代理技术。
由于是直接操纵字节码,效率十分高。常见的Groovy、Cglib都运用了ASM技术。

4.AspectJ

AspectJ全称Eclipse AspectJ,是一个简单易用高效的AOP框架,也是一种基于Java平台的语言。Java语言的编译器是javac,AspectJ语言的编译器是ajc。
AspectJ属于是静态织入,也就是说在编译期就织入完成,但是他的效率比Spring的AOP更高。

2.ProxyFactory 代理工厂

Spring不可能直接写Cglib或者JDK的动态代理,而是基于这俩做了封装,封装出来的类叫做ProxyFactory代表是一个代理工厂,专门负责创建代理对象。

CourseService target = new CourseService(); 
ProxyFactory proxyFactory = new ProxyFactory(); 
proxyFactory.setTarget(target); 
proxyFactory.addAdvice(new MethodInterceptor() { 
    @Override 
    public Object invoke(MethodInvocation invocation) throws Throwable {
        System.out.println("start before...");                                                                                                                   
        Object result = invocation.proceed(); 
        System.out.println("start after..."); 
        return result; 
        } 
        }); 
CourseService courseService = (CourseService) proxyFactory.getProxy(); 
courseService.test();

ProxyFactory会自动判断使用Cglib还是JDK动态代理。

3.Advice的分类

  • Before Advice:在方法执行之前触发。
  • After returning Advice:在方法return后触发。
  • After throwing Advice:在方法抛出异常后触发。
  • After finally Advice:在方法执行完finally和return后触发。
  • Around Advice:环绕触发模式,自定义触发时机。

4.Advisor

Advisor = Advice + Pointcut。Pointcut就是指需要代理的地方。

5.创建代理对象的方式

5.1 ProxyFactoryBean

利用FactoryBean的机制,通过@Bean给容器返回一个工厂Bean,最后通过工厂返回一个代理对象给容器。

5.2 BeanNameAutoProxyCreator

通过BeanNameAutoProxyCreator可以对目标Bean进行模式匹配进行AOP,但是他的缺点就是只能通过Bean的名字来指定目标对象。

5.3 DefaultAdvisorAutoProxyCreator

通过DefaultAdvisorAutoProxyCreator会通过BeanPostProcessor机制检查所有的Advisor类型的Bean,根据Advisor中的Pointcut和Advice逻辑来实现代理功能。常见的注解版本@ASspect、@Before、@Around等就是它的简化版本:

不过这种方式需要开启:@EnableAspectJAutoProxy注解。

6.Spring Aop概念

AOP本身代表面向切面编程,Spring提供了一套解决方案,可以通过简单的配置就可以实现面向切面的效果。Spring的AOP依赖了AspectJ,使用了AspectJ的一些核心注解,但是具体的解析工作和实现逻辑则是Spring自己处理的,例如常见的@Before、@After等等是AspectJ提供的。
Spring会将AspectJ的五个注解解析为Spring对应的Advice类:
@Before:AspectJMethodBeforeAdvice
@AfterReturning:AspectJAfterReturningAdvice
@AfterThrowing:AspectJAfterThrowingAdvice
@After:AspectJAfterAdvice
@Around:AspectJAroundAdvice
本质上来说就是个MethodInterceptor,当外部调用代理对象的方法时候就会触发方法拦截器来做方法执行前后的增强逻辑。

7.ProxyFactory对Cglib和JDK动态代理的选择

  - 如果开启了`@EnableAspectJAutoProxy`注解,并且`proxyTargetClass`属性赋予了true,那么无条件使用Cglib。
  - 如果需要代理的对象基于接口,且参数没有指定强制使用cglib则使用JDK的动态代理。

8.AbstractAdvisorAutoProxyCreator(AOP核心)

这个抽象类的实现类之一就是DefaultAdvisorAutoProxyCreator,这个抽象代理构建类从某种意义上来说,只要Spring IOC容器中有这个Bean的实现,就相当于是开启了AOP功能。
AbstractAdvisorAutoProxyCreator实现了BeanPostProcessor,所以它本质上来说也是一个Spring的后置处理器,在Spring Bean实例化后,在初始化前后会经过这个后置处理器的加工,从而来实现AOP的代理生成。
大致过程是:AbstractAdvisorAutoProxyCreator通过BeanPostProcessor机制来加工初始化后的Bean,找到容器中所有的Advisor(切点+切面逻辑),然后判断这个Bean是否存在Advisor所匹配的切点,如果匹配就表示当前这个初始化的Bean需要代理,此时就会通过ProxyFactory选择具体的动态代理手段来构建代理对象。

8.1 @EnableAspectJAutoProxy

这个注解的核心原理就是往IOC容器中Import了一个AnnotationAwareAspectJAutoProxyCreator类的Bean实例。这个类继承自AbstractAdvisorAutoProxyCreator,所以它本质上也是一个BeanPostProcessor后置处理器。
AnnotationAwareAspectJAutoProxyCreator除了可以找到所有的Advisor类型的Bean,还可以找到@Aspect注解的Bean,并将其解析为Advisor对象,然后走AOP的逻辑生成代理对象。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Minor王智

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值