AOP源码解析

一、AOP整体流程介绍

  

 

 

  1、spring 实例化单例bean,第一次调用后置处理器,解析切面@Aspect ,解析切面中的 @Pointcut @befor @after等,生成advisors(说明 一个 @before + 切点 生成一个advisor)

    1.1  org.springframework.context.support.AbstractApplicationContext#refresh() 方法

    1.2 org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization(beanFactory); // 实例化我们剩余的单实例bean.

    1.3 org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons 

    1.4 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean 创建bean方法

    1.5 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean()真正创建bean的方法

      Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 在此处调用 第一个后置处理器(InstantiationAwareBeanPostProcessor),解析切面,生成advisors ,进行缓存

    1.6 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation 

      InstantiationAwareBeanPostProcessor 后置处理器实现了 BeanpostProcessor ,有2个接口

      方法1:postProcessBeforeInitialization   在bean初始化之前调用,用于解析切面,生成advisors

      方法2:postProcessAfterInitialization  bean初始化之后调用,用于 生成代理对象

    1.7 org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip 

    1.8 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors

    1.9 org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors  解析切面类,构建advisors,存放到缓存中

    2.0 org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisor        -》 new InstantiationModelAwarePointcutAdvisorImp

二、AOP 触发时机说明

    1、在没有循环依赖的情况下,AOP生成代理 是在 bean的初始化完成以后(属性赋值之后)

      1.1 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean() 

      1.2 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization 

      1.3 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization 这里是bean的后置处理器的第九次调用,aop和事务都会在这里生存代理对象

      1.4 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary 

         根据当前bean找到匹配的 (一)中生成的advisor,匹配到了说明需要生成代理对象

      1.5 org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy 创建代理工厂,

        根据 当前bean是否实现接口,,是否设置ProxyTargetClass 属性 ,判断生成 jdk的代理工厂,还是cglib的代理工厂

        若我们  ProxyTargetClass 指定为false 且代理类是接口才会走jdk代理 否在我们还是cglib代理  ;;ProxyTargetClass 默认为false;

      1.6 JdkDynamicAopProxy ->Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); 生成代理对象

        CglibAopProxy 生成代理

    2、存在循环依赖的情况下,AOP生成代理 是在 bean 实例化以后

三、代理对象调用方法,进行增强

  以jdk动态代理为例:

  1. org.springframework.aop.framework.JdkDynamicAopProxy#invoke

    1.1 判断哪些方法不需要增强  (equals、hashcode 等方法无需增强)

    1.2 获取到目标对象

    1.3 找到适配到当前目标对象的所有的advisors;如果没有,,直接执行目标对象方法;如果有 先执行增强方法

    1.4 将目标对象的所有advisors 构造成一个 拦截器链一次执行, (说明:此处 使用的是 责任链模式) 这里用了责任链的设计模式,递归调用排序好的拦截器链

      执行顺序: @AfterTrrowing  @AfterReturning  @After  @Before 

  说明:jdk动态代理 本类方法 A 调用 B 不会走动态代理,,可以设置 expose属性

    1 jdk动态代理 底层使用的是 反射  InvocationHandler.invoke()方法,,生成的代理对象 实现了  接口  implements xxService.java

    2 cglib 动态代理底层使用的是 MethodInterceptor.interceptor()方法,生成的代理对象  继承了 被代理类,, extends xxAAAA.java  ;;底层使用的是 AMS

      效率问题:

      1.生成的代理的时候,,jdk 效率优于 cglib,因为 jdk生成一个文件,,cglib生成多个文件

      2. 调用的时候,,cglib优于 jdk,,因为 jdk 底层使用的是反射调用 ,cglib 是直接调用方法

 

  @EnableAspectJAutoProxy(proxyTargetClass = true,exposeProxy = true)

  proxyTargetClass = true 指定使用cglib动态代理,spring中如果实现了接口,默认使用jdk动态代理,未实现接口的情况下才使用cglib动态代理
  exposeProxy 将代理对象暴露到ThradLocal中,jdk动态代理中,同类中的A()方法,通过this.B()调用同类的B方法,AOP对B()方法不生效,因为此处的this获取的是
           类的对象,非代理对象,可以通过 AopContext.currentProxy()获取到代理对象调用B(),AOP会生效(此处需要设置exposeProxy = true)

      

      

 

posted @ 2022-03-11 17:56  wl_王麟  阅读(122)  评论(0编辑  收藏  举报