aop(Aspectj)源码分析
2022-01-12 17:41:12 6 举报
AI智能生成
登录查看完整内容
aop(Aspectj)源码分析
作者其他创作
大纲/内容
1. 在AopAutoConfiguration类中会引入@EnableAspectJAutoProxy,所以不需要手动引入配置到项目中
2. 如果项目的配置文件中spring.aop.proxy-target-class的值为false是使用jdk动态代理,为true使用cglib代理,springboot中该配置值默认为true
1. @EnableAspectJAutoProxy注解的自动开启
springboot内嵌初始化
关于ImportBeanDefinitionRegistrar的加载可查看springboot内嵌初始化#2.7.5.1.2.1.4.7.3.5
@EnableAspectJAutoProxy注解中会引入AspectJAutoProxyRegistrar类,该类实现了ImportBeanDefinitionRegistrar在registerBeanDefinitions方法中会注册AnnotationAwareAspectJAutoProxyCreatorbean
2. 注册AnnotationAwareAspectJAutoProxyCreator bean定义
doGetBean源码分析
setBeanFactory执行时机可查看doGetBean源码分析#4.7.1.4.5.8.1
由于AnnotationAwareAspectJAutoProxyCreator实现了BeanPostProcessor它的bean实例化时机是在springboot内嵌初始化#2.7.6,会比普通的bean先实例化,这样在普通bean实例化的时候才能执行该后置处理器
AnnotationAwareAspectJAutoProxyCreator 实现了BeanFactoryAware接口在初始化bean的时候会执行setBeanFactory方法,该方法中会触发aspectJAdvisorsBuilder的初始化
3. 实例化AnnotationAwareAspectJAutoProxyCreator bean定义到ioc容器
1. 获取缓存的key,默认为beanName,如果是工厂bean则会添加工厂bean前缀 font color=\"#0076b3\
2. 如果advisedBeans中已经存在该cacheKey则表示已经通知过了,直接放回null
Advice
Pointcut
Advisor
AopInfrastructureBean
1. 是基础设施类,比如是右侧的那些类 isInfrastructureClass(beanClass)
1. 通过父类的findCandidateAdvisors方法获取bean容器中实现了Advisor接口的bean List<Advisor> advisors = super.findCandidateAdvisors();
在 InstantiationModelAwarePointcutAdvisorImpl的构造方法中是通过ReflectiveAspectJAdvisorFactory#getAdvice方法适配成对应的通知对象
1. 最终会将Aspect中切面方法实例化成一个个 InstantiationModelAwarePointcutAdvisorImpl对象
2. 在循环体中获取到Aspect bean后就调用advisorFactory.getAdvisors方法进行解析了 List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory)
1. 判断this.aspectBeanNames是否为null,为null说明还没有被解析过 则循环容器中的bean,找出Aspect类型(有标注@Aspect注解)的bean进行解析
3. this.aspectBeanNames不为null则之前被解析过 则循环aspectBeanNames取出advisorsCache缓存中的值进行返回
2. this.aspectJAdvisorsBuilder不为空则(#3中有赋值) 则将@Aspect注解类, 解析成Advisor advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
1. 获取候选的Advisor列表 List<Advisor> candidateAdvisors = findCandidateAdvisors();
2. 循环上面的列表,如果Advisor为AspectJPointcutAdvisor类型且该Advisor#aspectName 为当前beanName则return true;
3. 调用父类的shouldSkip逻辑
2. 符合shouldSkip条件,此方法会里面会触发Advisor的加载 font color=\"#0076b3\
3. 如果符合右侧中的其中一种情况,则将该cacheKey添加到缓存,值为FALSE font color=\"#0076b3\
如果beanName不为空或targetSourcedBeans中不包含该beanName
4. 如果this.customTargetSourceCreators不为null 且某个TargetSourceCreator 能获取到当前beanClass的TargetSource,则直接生成的代理进行返回
1. postProcessBeforeInstantiation方法,该后置处理器方法中主要是会触发Advisor的加载
1. 以bean的Class 作为缓存的key,如果是工厂bean则会加上工厂bean的前缀 font color=\"#0076b3\
2. 将当前bean放入earlyProxyReferences缓存中 font color=\"#0076b3\
3. 调用warpIfNecessary方法判断如果满足代理条件则进行代理然后返回代理对象 这样依赖注入该对象的话注入的就是代理对象了font color=\"#0076b3\
2. getEarlyBeanReference方法,该方法主要是用来处理循环依赖时进行代理
1. 和#2.1中一样获取cacheKey font color=\"#0076b3\
2. 判断当前bean是否存在earlyProxyReferences缓存中 如果存在就不需要再进行代理了,因为#2.3中已经处理过了
1. 如果beanName存在targetSourcedBeans中则不进行代理,也就是#4.1.4中直接生成代理返回的情况
2. 如果cacheKey存在advisedBeans中且值为FALSE的则不进行代理
3. 和#4.1.3中的判断逻辑一样,对于符合其中一种条件的,不进行代理
1. 和#4.1.3.2.1一样获取候选的Advisor列表,前面已经指向过Aspectj的解析操作了 此处可以直接冲缓存中获取候选的Advisor列表 List<Advisor> candidateAdvisors = findCandidateAdvisors();
2. 对上一步的candidateAdvisors进行筛选,主要是遍历代理类的方法,如果看方法是否符合切面表达式的要求 font color=\"#0076b3\
3. 返回上一步获取的eligibleAdvisors return eligibleAdvisors;
1. 查找合格的Advisor font color=\"#0076b3\
2. 如果advisors.isEmpty()说明没有合格的Advisor则返回DO_NOT_PROXY
3. 有则将Advisor列表转为数组进行返回 return advisors.toArray();
4. 调用AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean方法查找合格的Advisorfont color=\"#0076b3\
5. 如果上一步获取到了合适的advisor,则进行代理操作,内部也是使用的ProxyFactory这个代理工厂类 可查看“spring ProxyFactory源码分析”
6. 将不需要代理的bean的cacheKey放入advisedBeans缓存中值为FALSE,在#4.3.3.2处就直接放回bean不进行代理了
3. 当前bean存在于earlyProxyReferences缓存中则调用 warpIfNecessary方法判断如果满足代理条件则进行代理操作 font color=\"#0076b3\
3. postProcessAfterInitialization方法
4. 普通bean实例化时执行bean后置处理器的相关方法
循环依赖注入时机可查看doGetBean源码分析#4.7.1.4.5.5.1循序依赖执行时机可查看doGetBean源码分析#2.5
AspectJAwareAdvisorAutoProxyCreator类关系图
aop(Aspectj)源码分析
0 条评论
回复 删除
下一页