这是我参与更文挑战的第17天,活动详情查看: 更文挑战
首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164…
Github : 👉 github.com/black-ant
当前案例源码 : 👉 Github AOP Source
一 . 前言
之前盘点了 IOC 的相关流程 , 这一篇终于来说一说 AOP 了 , 整个系列会从 :
- AOP 的初始化
- AOP 代理类的创建
- AOP 的拦截
- AOP 的代理方法调用
以上几个章节分别进行阐述
二 . AOP 的调用入口
Aop 的初始化是指在哪个环节开始 Aop 的配置 :
结合之前 IOC 了解到的 , Aop 的核心还是通过 postProcess 来完成 , 分为 Before 和 After 2个流程
- applyBeanPostProcessorsBeforeInstantiation (createBean 创建)
- applyBeanPostProcessorsAfterInitialization (initializeBean 是处理)
// 路线一 : 处理 Aware , 可以通过 getCustomTargetSource 提前生成代理
- C- AbstractAutowireCapableBeanFactory # createBean
- C- AbstractAutowireCapableBeanFactory # resolveBeforeInstantiation
- C- AbstractAutowireCapableBeanFactory # applyBeanPostProcessorsBeforeInstantiation
- C- AnnotationAwareAspectJAutoProxyCreator # postProcessBeforeInstantiation
// 路线二 : 处理 BeanPostProcessor , 正常代理创建逻辑
- C- AbstractAutowireCapableBeanFactory # createBean
- C- AbstractAutowireCapableBeanFactory # doCreateBean
- C- AbstractAutowireCapableBeanFactory # initializeBean
- C- AbstractAutowireCapableBeanFactory # applyBeanPostProcessorsAfterInitialization
1 | java复制代码// Step 1 : 在 createBean 中对 applyBeanPostProcessorsBeforeInstantiation 进行处理 |
处理后 , 在调用bean本身之前将委托给指定的拦截器 , 拦截器分为2种 :
- common : 为它创建的所有代理共享
- specific : 每个bean实例唯一
代理的限制 :
子类可以应用任何策略来决定一个bean是否要被代理,例如根据类型、名称、定义细节等
为什么有 getCustomTargetSource 提前生成 ?
getCustomTargetSource 是通过 TargetSourceCreator 对象 ,在 Bean 实例化之前 , 为其生成代理对象 .
该模式需要自行定制 , 详见 附录 : 创建 customTargetSource
2.1 applyBeanPostProcessorsBeforeInstantiation
Step 1 : 调用 PostProcessorsBefore C- AbstractAutowireCapableBeanFactory
此处主要会调用 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator 进行处理
1 | java复制代码for (BeanPostProcessor bp : getBeanPostProcessors()) { |
Step 2 : 配置前置条件 C- AbstractAutoProxyCreator
1 | java复制代码public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) { |
Step 2-1 : 返回目标实例
1 | java复制代码 |
2.2 applyBeanPostProcessorsAfterInitialization
前面说的是在 Bean 实例化之前创建代理 ,但是通常情况下 , 是在 Bean 实例化之后进行代理逻辑的创建
Step 1 : IOC initializeBean 入口
IOC initializeBean 时 , 调用 applyBeanPostProcessorsAfterInitialization 逻辑
1 | java复制代码if (mbd == null || !mbd.isSynthetic()) { |
Step 2 : applyBeanPostProcessorsAfterInitialization 中循环 BeanPostProcessor 进行处理
1 | java复制代码for (BeanPostProcessor processor : getBeanPostProcessors()) { |
PS : 可以看到 , 这里拿到的Bean 的 PostProcessor 就是 AnnotationAwareAspectJAutoProxyCreator
Step 3 : AbstractAutoProxyCreator # postProcessAfterInitialization 构建代理对象
如果bean被标识为代理,则使用配置的拦截器创建代理
1 | java复制代码public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) { |
Step 4 : wrapIfNecessary 正式创建代理类 C- AbstractAutoProxyCreator
1 | java复制代码 |
PRO21001 -> advisedBeans 的作用
1 | java复制代码// advisedBeans 用于标识当前 Bean 的代理状态 , 该对象 key 为 getCacheKey 获取 |
PRO21002 : TargetSource 是什么 ?
可以看到 , 这里实际上和下面的 applyBeanPostProcessorsAfterInitialization 类似 , 那么上面是处理什么?
TargetSource用于获取AOP调用的当前”目标” , 在Spring代理目标bean的时候,其并不是直接创建一个目标bean的对象实例的,而是通过一个TargetSource类型的对象将目标bean进行封装 , 然后通过 getTarget 获取目标对象
TargetSource 是一个接口 , 可以通过下图看到其本身的体系结构 :
三 . 补充点 : Advisors 详解之 getAdvicesAndAdvisorsForBean 流程
此部分对 getAdvicesAndAdvisorsForBean 的流程进行详细的浏览
Step 1 : 筛选 Advices C- AbstractAutoProxyCreator
1 | java复制代码M- getAdvicesAndAdvisorsForBean |
Step 2 : 为自动代理这个类找到所有符合条件的advisor
1 | java复制代码protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) { |
Step 2-1 : BeanFactoryAdvisorRetrievalHelper 获取通知对象
2-1-1 : 先调用具体实现类 (AnnotationAwareAspectJAutoProxyCreator)
👉该过程中对切面进行了扫描 ,并且缓存了所有的通知点
1 | java复制代码protected List<Advisor> findCandidateAdvisors() { |
PIC0001 : 切面元数据
PIC0002 : 待通知的切点
2-1-2 : 调用父类
1 | java复制代码protected List<Advisor> findCandidateAdvisors() { |
2-1-3 : 实际方法
1 | java复制代码public List<Advisor> findAdvisorBeans() { |
Step 2-2 : 搜索给定的候选advisor以找到适用于指定bean的所有advisor
1 | java复制代码 |
Step 2-3 : sort 排序
1 | java复制代码protected List<Advisor> sortAdvisors(List<Advisor> advisors) { |
总结
AOP 初始化阶段基本上就完成了 , 后续再来看一下代理类的创建 . 来总结一下这篇文档得所有概念 :
- 由 initializeBean 开启 AOP 的主处理逻辑
- AbstractAutowireCapableBeanFactory 调用 applyBeanPostProcessorsBeforeInstantiation 创建自定义代理类
- AbstractAutowireCapableBeanFactory 调用 applyBeanPostProcessorsAfterInitialization 筛选通知器
附录 : 创建 customTargetSource
参考地址 (原文这一块写的更加详细) @ blog.csdn.net/qq_39002724…
Step 1 :准备 CustomTargetSource
1 | java复制代码public class DefaultCustomTargetSource extends AbstractBeanFactoryBasedTargetSource { |
Step 2 : 准备创建者
该对象用于返回创建的 CustomTargetSource
1 | java复制代码public class DefaultCustomerTargetSourceCreator extends AbstractBeanFactoryBasedTargetSourceCreator { |
Step 3 : CustomTargetSource 资源配置
1 | java复制代码@Component |
本文转载自: 掘金