📫作者简介:zhz小白
公众号:小白的Java进阶之路
专业技能:
1、Java基础,并精通多线程的开发,熟悉JVM原理
2、熟悉Java基础,并精通多线程的开发,熟悉JVM原理,具备⼀定的线上调优经验
3、熟悉MySQL数据库调优,索引原理等,⽇志原理等,并且有出过⼀篇专栏
4、了解计算机⽹络,对TCP协议,滑动窗⼝原理等有⼀定了解
5、熟悉Spring,Spring MVC,Mybatis,阅读过部分Spring源码
6、熟悉SpringCloud Alibaba体系,阅读过Nacos,Sentinel,Seata,Dubbo,Feign,Gateway核⼼源码与设计,⼆次开发能⼒
7、熟悉消息队列(Kafka,RocketMQ)的原理与设计
8、熟悉分库分表ShardingSphere,具有真实⽣产的数据迁移经验
9、熟悉分布式缓存中间件Redis,对其的核⼼数据结构,部署架构,⾼并发问题解决⽅案有⼀定的积累
10、熟悉常⽤设计模式,并运⽤于实践⼯作中
11、了解ElasticSearch,对其核⼼的原理有⼀定的了解
12、了解K8s,Jekins,GitLab
13、了解VUE,GO
14、⽬前有正在利⽤闲暇时间做互游游戏,开发、运维、运营、推销等
本人著作git项目:https://gitee.com/zhouzhz/star-jersey-platform,有兴趣的可以私聊博主一起编写,或者给颗star
领域:对支付(FMS,FUND,PAY),订单(OMS),出行行业等有相关的开发领域
🔥如果此文还不错的话,还请👍关注、点赞、收藏三连支持👍一下博主~
文章目录
- 1、@EnableAspectJAutoProxy有什么用?
- 2、@EnableAspectJAutoProxy的源码解析
- 2.1、初入@EnableAspectJAutoProxy源码
- 2.2、@Import注解引入AspectJAutoProxyRegistrar
- 2.3、开始阅读AspectJAutoProxyRegistrar源码
- 2.4、开始阅读AnnotationAwareAspectJAutoProxyCreator
- 2.4.1、AnnotationAwareAspectJAutoProxyCreator的类结构图
- 2.4.2、开始阅读AnnotationAwareAspectJAutoProxyCreator的源码,了解其内部运作
- 2.4.2.1、debug一下AnnotationConfigApplicationContext
- 2.4.2.2、org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>...)
- 2.4.2.3、org.springframework.context.support.AbstractApplicationContext#refresh
- 2.4.2.4、org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors
- 2.4.2.5、org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
- 2.4.2.6、org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
- 2.4.2.7、org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
- 2.4.2.8、org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
- 2.4.2.9、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
- 2.4.2.10、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
- 2.4.2.11、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
- 2.4.2.12、org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory
- 2.4.2.13、AnnotationAwareAspectJAutoProxyCreator是怎么执行的?
- 2.4.3、汇总以下AnnotationAwareAspectJAutoProxyCreator的处理
- 2.4.4、AnnotationAwareAspectJAutoProxyCreator的作用是什么呢?
- 2.4.4.1、postProcessBeforeInstantiation
- 2.4.4.2、postProcessAfterInitialization
- 原文连接(本人其他平台)
1、@EnableAspectJAutoProxy有什么用?
- @EnableAspectJAutoProxy代表我们可以开启注解版的AOP功能,也就是说我们要想使用注解版的AOP,就必须在启动类/配置类(@Configuration)中添加@EnableAspectJAutoProxy。
2、@EnableAspectJAutoProxy的源码解析
废话不多说,让我们来看一下@EnableAspectJAutoProxy的核心源码吧
2.1、初入@EnableAspectJAutoProxy源码
2.2、@Import注解引入AspectJAutoProxyRegistrar
首先看AspectJAutoProxyRegistrar之前我们可以先行去了解下@Import注解如何注册一个Bean,具体如下:【Spring【IOC】】——7、@Import注解给容器中快速导入一个组件
接着我们再来进入AspectJAutoProxyRegistrar中,可以发现它继承了ImportBeanDefinitionRegistrar,重写了其中的void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);方法,源码如下:
所以我们可以知道**@EnableAspectJAutoProxy注解使用AspectJAutoProxyRegistrar对象自定义组件,并将相应的组件添加到了IOC容器中。**
那么大家好不好奇为什么他要通过AspectJAutoProxyRegistrar去继承ImportBeanDefinitionRegistrar,然后在其实现方法中注册一个Bean呢?那么这个Bean是什么呢?接下来我们开始debug其源码,从而深入去探讨@EnableAspectJAutoProxy。
2.3、开始阅读AspectJAutoProxyRegistrar源码
我们先在AspectJAutoProxyRegistrar的registerBeanDefinitions方法中添加一个断点,如下
然后我们一直进去,先后会执行以下代码
- org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry)
- org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
- org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired
- org.springframework.aop.config.AopConfigUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
一直到org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired中我们就可以看到其核心逻辑,代码如下:
我们可以发现他在第一次进来的时候其实会创建一个key为:org.springframework.aop.config.internalAutoProxyCreator
,value: AnnotationAwareAspectJAutoProxyCreator.class的RootBeanDefinition并返回。
然后我们执行完这个方法之后,就会回来到下面红圈里面的方法,这一行的本质是将注解中的所有属性转成Map。
具体的结果如下所示:
- 通过AnnotationConfigUtils类的attributesFor()方法来获取@EnableAspectJAutoProxy注解的信息。
- 判断proxyTargetClass属性的值是否为true
- 若为true则调用AopConfigUtils类的forceAutoProxyCreatorToUseClassProxying()方法;
-
这里就是获取AnnotationAwareAspectJAutoProxyCreator的BeanDefinition,然后往属性中设置"proxyTargetClass"=true
- 若为true则调用AopConfigUtils类的forceAutoProxyCreatorToUseClassProxying()方法;
- 判断exposeProxy属性的值是否为true
- 若为true则调用AopConfigUtils类的forceAutoProxyCreatorToExposeProxy()方法,本质是暴露一些Bean
-
这里就是获取AnnotationAwareAspectJAutoProxyCreator的BeanDefinition,然后往属性中设置"exposeProxy"=true。
- 若为true则调用AopConfigUtils类的forceAutoProxyCreatorToExposeProxy()方法,本质是暴露一些Bean
- 判断proxyTargetClass属性的值是否为true
至此AspectJAutoProxyRegistrar类就已经完结了。
综上所述,向Spring的配置类上添加@EnableAspectJAutoProxy注解之后,会向IOC容器中注册AnnotationAwareAspectJAutoProxyCreator,也就是创建注解装配模式的AspectJ切面自动代理创建器
2.4、开始阅读AnnotationAwareAspectJAutoProxyCreator
上面2.3中我们发现@EnableAspectJAutoProxy注解本质上是往容器中添加一个AnnotationAwareAspectJAutoProxyCreator类,那么我们是不是要去了解AnnotationAwareAspectJAutoProxyCreator是一个什么样的东西呢?
2.4.1、AnnotationAwareAspectJAutoProxyCreator的类结构图
2.4.2、开始阅读AnnotationAwareAspectJAutoProxyCreator的源码,了解其内部运作
首先我们可以通过debug程序,具体可以先去看一下前面的章节《20、搭建一个AOP测试环境?》,我们主要是根据这个程序去研究AnnotationAwareAspectJAutoProxyCreator后置处理器的实现。
我们可以先去看一下栈帧,如下
2.4.2.1、debug一下AnnotationConfigApplicationContext
首先我们debug之后,会发现他会先停在AnnotationConfigApplicationContext这个创建对象上,如下
2.4.2.2、org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>…)
然后接着来会进入到AnnotationConfigApplicationContext内部调用refresh()方法区刷新容器,刷新容器就是要把容器中的所有bean都创建出来,也就是说这就像初始化容器一样。
2.4.2.3、org.springframework.context.support.AbstractApplicationContext#refresh
我们会进入refresh()方法里面的,并且会执行到下面这一行重要代码,
//注册Bean处理器,然后拦截bean创建。
registerBeanPostProcessors(beanFactory);
2.4.2.4、org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors
然后我们进入registerBeanPostProcessors方法中,看一下其核心实现,她就是调用了 PostProcessorRegistrationDelegate的registerBeanPostProcessors(beanFactory, this)静态方法。代码如下:
2.4.2.5、org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
首先我们先全局看一下这个方法的代码,代码如下:
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22
//先按照类型拿到IOC容器中所有需要创建的后置处理器,即先获取IOC容器中已经定义了的需要创建对象的所有BeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
/**
* 在已有的BeanPostProcessor中,如下
* 0 = {ApplicationContextAwareProcessor@2260}
* 1 = {ApplicationListenerDetector@2261}
* 2 = {ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor@2262}
* 添加一个下面的BeanPostProcessor检查器,
* 3 = {PostProcessorRegistrationDelegate$BeanPostProcessorChecker@2264}
*/
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
接着我们开始讲解一下这段代码的意思,让我们充分了解每一行的来源,然后我们进入到PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);方法中,此时会按照下面流程执行
- 1、先按照类型拿到IOC容器中所有需要创建的后置处理器,即先获取IOC容器中已经定义了的需要创建对象的所有BeanPostProcessor。(Spring在创建IOC容器的时候会先传入配置类,然后配置类中会有一个注解@EnableAspectJAutoProxy,而这个注解会注册一个AnnotationAwareAspectJAutoProxyCreator后置处理器(看前面),还有一些spring默认的后置处理器和我们自定义的后置处理器,具体如下)。
接着我们继续看下去,发现他执行了,下面这行代码去添加一个beanPostProcessor,
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));具体意思如下:
然后我们我们可以继续看到其下面有四行代码,如下:
//实现了PriorityOrdered接口
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
//类型是MergedBeanDefinitionPostProcessor的BeanPostProcessor
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
//实现了Ordered接口
List<String> orderedPostProcessorNames = new ArrayList<>();
//原生的BeanPostProcessor
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
其作用是什么呢?主要是分离BeanPostProcessor,不同的BeanPostProcessor的执行顺序不同,具体为上面的代码解释。
- 优先注册实现了PriorityOrdered接口的BeanPostProcessor
- 如果类型是MergedBeanDefinitionPostProcessor的BeanPostProcessor
- 再给容器中注册实现了Ordered接口的BeanPostProcessor
- 最后再注册没实现优先级接口的BeanPostProcessor
我们可以自行查看一下org.springframework.aop.config.internalAutoProxyCreator的Bean名称的组件,即是AnnotationAwareAspectJAutoProxyCreator,他的底层类ProxyProcessorSupport实现了Ordered,所以他最终会进入到orderedPostProcessorNames这个list中,代码如下:
接着他会按照以下顺序是去执行注册BeanPostProcessor,如下:
- 注册是priority的BeanPostProcessor
- 注册是ordered的BeanPostProcessor
- 注册原生的BeanPostProcessor
- 注册是priority并且类型是MergedBeanDefinitionPostProcessor的BeanPostProcessor
- 注册一个ApplicationListenerDetector的检测器(注册一个新的)
然后这个方法我们就讲完了。
2.4.2.6、org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
然后他会按照下面的执行顺序去执行代码:
- org.springframework.beans.factory.BeanFactory#getBean(java.lang.String, java.lang.Class)
- org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Class)
- org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
- org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Class)
就会执行到我们这个部分要讲的核心代码了,这段代码有点长,我们直接看核心,在这段代码中有个函数表达式,关于函数表达式的执行顺序,大家可以看一下下面的数字,他会按照0-4执行。
省略代码来看就是下面:
AbstractBeanFactory#200
// 0
sharedInstance = this.getSingleton(beanName, () -> {
try {
return this.createBean(beanName, mbd, args);// 3
} catch (BeansException var5) {
this.destroySingleton(beanName);
throw var5;
}
});
DefaultSingletonBeanRegistry#113
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {// 1
singletonObject = singletonFactory.getObject();// 2
...// 4
}
我们分析一下这段代码,他其实就是从容器中获取单例Bean,具体的逻辑也就是下一部分的核心代码逻辑。
2.4.2.7、org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
第一次创建Bean的时候,是会执行到下面的DefaultSingletonBeanRegistry类的getSingleton()方法中,如果是第一次获取单实例的Bean获取不到时,就会调用singletonObject = singletonFactory.getObject();也就是下面截图的代码那
2.4.2.8、org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
接着debug他就会到AbstractBeanFactory的doGetBean()方法中,我们可以见名思意发现他就是创建Bean的,也就是说如果getSingleton获取不到Bean的话,我们就通过createBean创建Bean。
2.4.2.9、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
接着我们会经历很长的一部分调用,知道调到AbstractAutowireCapableBeanFactory#createBean方法,执行流程如下:
- org.springframework.beans.factory.support.AbstractBeanFactory#createBean
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
源代码如下,他会一直执行到doCreateBean方法
2.4.2.10、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
然后当他执行到doCreateBean()方法,准备创建Bean的时候,这个方法会做很多事情,比如Bean的实例化,Bean的属性填充,Bean的初始化,销毁等等,但是对于我们这个AnnotationAwareAspectJAutoProxyCreator的后置处理器来说,他是在执行到exposedObject = initializeBean(beanName, exposedObject, mbd);方法,就会处理的,因此我们直接看initializeBean()初始化方法。
接下来他会进入到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)方法中。
2.4.2.11、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
在进入到initizeBean之后,他会进行一系列的aware回调,其中有一段逻辑他是他会当我们的Bean实现了BeanFactoryAware,他就会把BeanFactory设置成AbstractAutowireCapableBeanFactory,而恰巧我们的AnnotationAwareAspectJAutoProxyCreator他就实现了BeanFactoryAware,具体大家可以看上面的解释,然后他就又会去调用所有的BeanPostProcessor的postProcessBeforeInitialization()方法,再调用初始化方法,也就是init-method,InitializingBean的相关方法,最后执行BeanPostProcessor的postProcessAfterInitialization()方法。
我们上面讲到了他会执行BeanFactoryAware相关的实现类,那么我们是不是可以定位到org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory方法
2.4.2.12、org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory
他会进入到AbstractAdvisorAutoProxyCreator的setBeanFactory中去设置BeanFactory,然后会执行到initBeanFactory()中,去初始化BeanFactory。
然后就会调到AnnotationAwareAspectJAutoProxyCreator#initBeanFactory中执行以下代码,主要是创建两个类ReflectiveAspectJAdvisorFactory和BeanFactoryAspectJAdvisorsBuilderAdapter,相当于把之前创建的aspectJAdvisorFactory以及beanFactory重新包装了一下。
因此整个流程就讲完了。
2.4.2.13、AnnotationAwareAspectJAutoProxyCreator是怎么执行的?
AnnotationAwareAspectJAutoProxyCreator它实现了SmartInstantiationAwareBeanPostProcessor并且继承了InstantiationAwareBeanPostProcessor,所以他的初始化前后的方法名分别为postProcessBeforeInstantiation,postProcessAfterInstantiation,而在我们上面讲的org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])方法中,在其里面调用了如下代码:
在resolveBeforeInstantiation()方法里面调用了applyBeanPostProcessorsBeforeInstantiation()和applyBeanPostProcessorsAfterInitialization()两个方法。
其内部的逻辑分别是,从而调用了继承InstantiationAwareBeanPostProcessor的类的两个实例化前后方法
@Nullable
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
return null;
}
@Override
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessAfterInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
所以我们可以得出结论:
- AnnotationAwareAspectJAutoProxyCreator会在任何bean创建之前,先尝试返回bean的实例
- AnnotationAwareAspectJAutoProxyCreator在所有bean创建之前,会有一个拦截,因为它是InstantiationAwareBeanPostProcessor这种类型的后置处理器,然后会调用它的postProcessBeforeInstantiation()方法。
2.4.3、汇总以下AnnotationAwareAspectJAutoProxyCreator的处理
- org.springframework.context.support.AbstractApplicationContext#refresh
- org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors
- org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
- org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String, java.lang.Class)
- org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
- org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String, org.springframework.beans.factory.ObjectFactory<?>)
- org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
- 最后就是执行initializeBean的里面的
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
- org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
- 至此AnnotationAwareAspectJAutoProxyCreator就创建完成了,最后拿到所有的BeanPostProcessor,然后调用beanFactory的addBeanPostProcessor()方法将BeanPostProcessor注册到BeanFactory中。(这里可以看一下PostProcessorRegistrationDelegate#registerBeanPostProcessors(ConfigurableListableBeanFactory,AbstractApplicationContext)里面的),我们可以看一下registerBeanPostProcessors(beanFactory, internalPostProcessors);因为AnnotationAwareAspectJAutoProxyCreator会放入internalPostProcessors中,就可以发现他的本质就是上面红色那句话。
2.4.4、AnnotationAwareAspectJAutoProxyCreator的作用是什么呢?
首先我们通过上面的内容可知,在每一个bean创建之前,都会调用**postProcessBeforeInstantiation()**方法,**postProcessAfterInitialization()**方法。所以我们重点看一下AnnotationAwareAspectJAutoProxyCreator的
**postProcessBeforeInstantiation()和postProcessAfterInitialization()**方法。
2.4.4.1、postProcessBeforeInstantiation
我们直接看AbstractAutoProxyCreator的postProcessBeforeInstantiation方法,他是AnnotationAwareAspectJAutoProxyCreator的核心,具体代码如下:
解析:
-
1、先获取缓存的key,可以发现如果BeanName为空,就返回BeanClass,BeanName不为空,就判断当前beanClass是否是FactoryBean,是的话就返回&+beanName,不是的话就返回beanName。
-
2、判断名为targetSourcedBeans的Set集合里面是否包含有这个bean的名称,但是targetSourcedBeans是一个空的集合
- 2.1、判断当前bean是否在advisedBeans中
- advisedBeans:里面保存了所有需要增强的bean的名称
- 为什么叫需要增强的bean?简单理解就是通过aop切面代理后的bean,列如日志aop类大家应该都熟悉吧。
- 2.1、判断当前bean是否在advisedBeans中
-
3、判断当前bean是否是基础类型,或者是否是切面(标注了@Aspect注解的)
- 3.1、我们可以发现isInfrastructureClass方法中,他执行了两块代码,分别是
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#isInfrastructureClass
- org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass
- 可以总结出isInfrastructureClass:判断当前bean是否是基础类型,或者是否是切面(标注了@Aspect注解的),其中基础类型涉及的注解有Advice,Pointcut,Advisor,AopInfrastructureBean。
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#isInfrastructureClass
- 3.2、判断是否需要跳过
-
在这里首先是调用findCandidateAdvisors()方法找到候选的增强器的集合:所谓的增强器其实就是切面里面的那些通知方法,只不过,在这儿是把通知方法的详细信息包装成了一个Advisor,并将其存放在了一个List集合中,即增强器的集合,即是说,每一个通知方法都会被认为是一个增强器。并且每一个通知方法都是InstantiationModelAwarePointcutAdvisor类型的,并且我们还可以发现是@Aspect修饰的类的aop方法。
-
判断当前Advisor是否是AspectJPointcutAdvisor这种类型的,如果是,那么返回true。然而在我们这肯定不是,因为都是InstantiationModelAwarePointcutAdvisor类型的,所以不会进,因此会调用super.shouldSkip(beanClass, beanName)
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip
- org.springframework.aop.framework.autoproxy.AutoProxyUtils#isOriginalInstance,这里会判断当前的beanName是否为空或者beanName的长度不等于beanClass的长度+“.ORIGINAL"的长度,是的话就返回false,不是的话就判断beanName的开始是否等于beanClass的名字和beanName的结束是否等于”.ORIGINAL"。
- org.springframework.aop.framework.autoproxy.AutoProxyUtils#isOriginalInstance,这里会判断当前的beanName是否为空或者beanName的长度不等于beanClass的长度+“.ORIGINAL"的长度,是的话就返回false,不是的话就判断beanName的开始是否等于beanClass的名字和beanName的结束是否等于”.ORIGINAL"。
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip
-
- 3.1、我们可以发现isInfrastructureClass方法中,他执行了两块代码,分别是
-
4、如果是配置类,比如我们前面的章节里面的MainConfig的话,那么3就会返回false,就不会执行if里面的语句。并且下面中TargetSource也会为空,所以postProcessBeforeInstantiation()方法整体会返回null。
因此,我们可以发现,在每次创建bean的时候,都会先调用postProcessBeforeInstantiation()方法,然后再调用postProcessAfterInitialization()方法。
2.4.4.2、postProcessAfterInitialization
解析(我们还是基于MainConfig来讲):
- 1、首先我们看一下传入当前方法的Bean是否为空,我们很清晰的可以发现bean就是ManConfig,所以他要进入if。
- 2、先获取缓存的key,可以发现如果BeanName为空,就返回BeanClass,BeanName不为空,就判断当前beanClass是否是FactoryBean,是的话就返回&+beanName,不是的话就返回beanName。所以对于我们当前来说,他返回的就是mainConfig。
-
3、判断名为earlyProxyReferences的Set集合里面是否包含当前bean,在该Set集合里面我们可以看到之前已经代理过了什么,目前该Set集合是一个空集合。因为当前earlyProxyReferences是肯定不包括,所以会进入到wrapIfNecessary(bean, beanName, cacheKey)。
-
4、判断哪些情况下是需要包装的。(wrapIfNecessary()方法调用完之后,最终会给容器中返回当前组件使用cglib增强了的代理对象)
-
4.1、首先是拿到MainConfig这个bean的名称(即mainConfig),然后再来判断名为targetSourcedBeans的Set集合里面是否包含有这个bean的名称,只不过此时该Set集合是一个空集合。
-
4.2、判断名为advisedBeans的Map集合里面是否包含有当前bean的名称。我在前面也说过了advisedBeans这个东东,它就是一个Map集合,里面保存了所有需要增强的bean的名称。
-
4.3、由于这儿是第一次来处理当前bean,所以名为advisedBeans的Map集合里面是不包含MainConfig这个bean的名称的。
-
4.4、判断当前bean是否是基础类型,或者是否是切面(标注了@Aspect注解的)
-
4.4.1、我们可以发现isInfrastructureClass方法中,他执行了两块代码,分别是
-
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#isInfrastructureClass
-
org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass
-
可以总结出isInfrastructureClass:判断当前bean是否是基础类型,或者是否是切面(标注了@Aspect注解的),其中基础类型涉及的注解有Advice,Pointcut,Advisor,AopInfrastructureBean。
-
-
4.4.2、判断是否需要跳过
-
在这里首先是调用findCandidateAdvisors()方法找到候选的增强器的集合:所谓的增强器其实就是切面里面的那些通知方法,只不过,在这儿是把通知方法的详细信息包装成了一个Advisor,并将其存放在了一个List集合中,即增强器的集合,即是说,每一个通知方法都会被认为是一个增强器。并且每一个通知方法都是InstantiationModelAwarePointcutAdvisor类型的,并且我们还可以发现是@Aspect修饰的类的aop方法。
-
判断当前Advisor是否是AspectJPointcutAdvisor这种类型的,如果是,那么返回true。然而在我们这肯定不是,因为都是InstantiationModelAwarePointcutAdvisor类型的,所以不会进,因此会调用super.shouldSkip(beanClass, beanName)
-
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip
- org.springframework.aop.framework.autoproxy.AutoProxyUtils#isOriginalInstance,这里会判断当前的beanName是否为空或者beanName的长度不等于beanClass的长度+“.ORIGINAL"的长度,是的话就返回false,不是的话就判断beanName的开始是否等于beanClass的名字和beanName的结束是否等于”.ORIGINAL"。
- org.springframework.aop.framework.autoproxy.AutoProxyUtils#isOriginalInstance,这里会判断当前的beanName是否为空或者beanName的长度不等于beanClass的长度+“.ORIGINAL"的长度,是的话就返回false,不是的话就判断beanName的开始是否等于beanClass的名字和beanName的结束是否等于”.ORIGINAL"。
-
-
-
4.4.3、如果上面两条件有一个是true的话,就设置增强advisedBeans的map为cacheKey,false。然后返回bean。
-
-
4.5、获取当前bean的所有增强器,调用getAdvicesAndAdvisorsForBean()方法获取当前bean的所有增强器,也就是那些通知方法,最终封装成这样一个Object[] specificInterceptors数组。
- 4.5.1、org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean
- 4.5.1.1、org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
-
4.5.1.1.1、获取所有的mainConfig的这个类型的所有的可用的增强器
- 4.5.1.1.1.1、进入其中就可以发现,其第一步是获取候选的所有增强器,也就是@Aspect的各种定义的通知类型方法(前置,后置,环绕,后置。。。)
- 4.5.1.1.1.2、找到候选的所有增强器,也就是说是来找哪些通知方法是需要切入到当前bean的目标方法中的。
- 4.5.1.1.1.2.1、org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply,它是用AopUtils工具类来找到所有能用的增强器(通知方法)的。
- 4.5.1.1.1.2.1.1、然后我们可以进入到org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply,看一下其核心源码,本质上就是表达式匹配所有可用的增强器,从而把他添加到一个list中,并返回
- 4.5.1.1.1.2.1.1、然后我们可以进入到org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply,看一下其核心源码,本质上就是表达式匹配所有可用的增强器,从而把他添加到一个list中,并返回
- 4.5.1.1.1.2.1、org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply,它是用AopUtils工具类来找到所有能用的增强器(通知方法)的。
- 4.5.1.1.1.1、进入其中就可以发现,其第一步是获取候选的所有增强器,也就是@Aspect的各种定义的通知类型方法(前置,后置,环绕,后置。。。)
-
- 4.5.1.1、org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
- 4.5.1、org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean
-
最后一个canApply的源码。
- 4.5.1.1.1.3、如果eligibleAdvisors不为空,就会进行排序,也就是说调用哪些通知方法,是有顺序的。然后进行返回。
- 4.5.1.2、如果findEligibleAdvisors(beanClass, beanName)返回为空,就返回null,也就是空Object[],返回就正常返回。
- 4.5.2、现在specificInterceptors的Object[]数组里面已经具有了那些指定好的增强器,这些增强器其实就是要拦截目标方法执行的。
- 4.5.3、总结一下
- 找到候选的所有增强器,也就是说是来找哪些通知方法是需要切入到当前bean的目标方法中的
- 获取到能在当前bean中使用的增强器
- 给增强器排序
-
4.6、保存当前bean在advisedBeans中,表示这个当前bean已经被增强处理了
- 接着进入到createProxy中,也就是最核心的创建代理的方法,具体代码流程如下:
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
-
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#buildProxy,这里我们只看最后一步,其他代码都是一些过滤。
- proxyFactory.getProxyClass(classLoader),一般情况下不会调用当前方法,因此我们可以看一下前面传进来的classOnly他是false,重点看下面这个。
- proxyFactory.getProxy(classLoader)),具体代码如下,我们直接看一下getProxy的实现。
- 我们可以发现getProxy会有两个实现,一个是jdk,一个是cglib,spring会分析如果当前类是有实现接口的,那么就使用jdk来创建动态代理,如果当前类没有实现接口,此时jdk是没法创建动态代理的,那么自然就得使用cglib来创建动态代理了。对于我们当前来说是cglib,spring也可以设置所有的代理都用cglib,只需要配置类开启@EnableAspectJAutoPrxy(proxyTargetClass = true),具体的更详细的可以自行百度。
- 我们可以发现getProxy会有两个实现,一个是jdk,一个是cglib,spring会分析如果当前类是有实现接口的,那么就使用jdk来创建动态代理,如果当前类没有实现接口,此时jdk是没法创建动态代理的,那么自然就得使用cglib来创建动态代理了。对于我们当前来说是cglib,spring也可以设置所有的代理都用cglib,只需要配置类开启@EnableAspectJAutoPrxy(proxyTargetClass = true),具体的更详细的可以自行百度。
-
- org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy
- 接着进入到createProxy中,也就是最核心的创建代理的方法,具体代码流程如下:
-
4.7、设置代理类,返回
总结: -
获取所有增强器,所谓的增强器就是切面里面的那些通知方法。
-
然后再把这些增强器保存到代理工厂(即proxyFactory)中。
-
为当前组件创建代理对象,并且会有两种形式的代理对象,它们分别如下,最终Spring会自动决定,是为当前组件创建jdk的动态代理,还是创建cglib的动态代理。
- 一种是JdkDynamicAopProxy这种形式的,即jdk的动态代理
- 一种是ObjenesisCglibAopProxy这种形式的,即cglib的动态代理
原文连接(本人其他平台)
https://www.yuque.com/zhzbaishen/ldbu6i/epbql4eoegtomgce?singleDoc# 《21、@EnableAspectJAutoProxy注解详解?》