一、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)