【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?
  4mHcszqpqM94 2023年11月02日 17 0


📫作者简介: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源码

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java


2.2、@Import注解引入AspectJAutoProxyRegistrar

首先看AspectJAutoProxyRegistrar之前我们可以先行去了解下@Import注解如何注册一个Bean,具体如下:【Spring【IOC】】——7、@Import注解给容器中快速导入一个组件

接着我们再来进入AspectJAutoProxyRegistrar中,可以发现它继承了ImportBeanDefinitionRegistrar,重写了其中的void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry);方法,源码如下:

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_02


所以我们可以知道**@EnableAspectJAutoProxy注解使用AspectJAutoProxyRegistrar对象自定义组件,并将相应的组件添加到了IOC容器中。**

那么大家好不好奇为什么他要通过AspectJAutoProxyRegistrar去继承ImportBeanDefinitionRegistrar,然后在其实现方法中注册一个Bean呢?那么这个Bean是什么呢?接下来我们开始debug其源码,从而深入去探讨@EnableAspectJAutoProxy。


2.3、开始阅读AspectJAutoProxyRegistrar源码

我们先在AspectJAutoProxyRegistrar的registerBeanDefinitions方法中添加一个断点,如下

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_03


然后我们一直进去,先后会执行以下代码


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#registerOrEscalateApcAsRequired中我们就可以看到其核心逻辑,代码如下:

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_04


我们可以发现他在第一次进来的时候其实会创建一个key为:org.springframework.aop.config.internalAutoProxyCreator

,value: AnnotationAwareAspectJAutoProxyCreator.class的RootBeanDefinition并返回。

然后我们执行完这个方法之后,就会回来到下面红圈里面的方法,这一行的本质是将注解中的所有属性转成Map。


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_05

具体的结果如下所示:

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_06


通过AnnotationConfigUtils类的attributesFor()方法来获取@EnableAspectJAutoProxy注解的信息。

判断proxyTargetClass属性的值是否为true

若为true则调用AopConfigUtils类的forceAutoProxyCreatorToUseClassProxying()方法;


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_07

这里就是获取AnnotationAwareAspectJAutoProxyCreator的BeanDefinition,然后往属性中设置"proxyTargetClass"=true


判断exposeProxy属性的值是否为true

若为true则调用AopConfigUtils类的forceAutoProxyCreatorToExposeProxy()方法,本质是暴露一些Bean

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_08


这里就是获取AnnotationAwareAspectJAutoProxyCreator的BeanDefinition,然后往属性中设置"exposeProxy"=true。


至此AspectJAutoProxyRegistrar类就已经完结了。

综上所述,向Spring的配置类上添加@EnableAspectJAutoProxy注解之后,会向IOC容器中注册AnnotationAwareAspectJAutoProxyCreator,也就是创建注解装配模式的AspectJ切面自动代理创建器


2.4、开始阅读AnnotationAwareAspectJAutoProxyCreator

上面2.3中我们发现@EnableAspectJAutoProxy注解本质上是往容器中添加一个AnnotationAwareAspectJAutoProxyCreator类,那么我们是不是要去了解AnnotationAwareAspectJAutoProxyCreator是一个什么样的东西呢?


2.4.1、AnnotationAwareAspectJAutoProxyCreator的类结构图

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_09


2.4.2、开始阅读AnnotationAwareAspectJAutoProxyCreator的源码,了解其内部运作

首先我们可以通过debug程序,具体可以先去看一下前面的章节《20、搭建一个AOP测试环境?》,我们主要是根据这个程序去研究AnnotationAwareAspectJAutoProxyCreator后置处理器的实现。

我们可以先去看一下栈帧,如下

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_10


2.4.2.1、debug一下AnnotationConfigApplicationContext

首先我们debug之后,会发现他会先停在AnnotationConfigApplicationContext这个创建对象上,如下

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_11


2.4.2.2、org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class<?>…)

然后接着来会进入到AnnotationConfigApplicationContext内部调用refresh()方法区刷新容器,刷新容器就是要把容器中的所有bean都创建出来,也就是说这就像初始化容器一样。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_12


2.4.2.3、org.springframework.context.support.AbstractApplicationContext#refresh

我们会进入refresh()方法里面的,并且会执行到下面这一行重要代码,


//注册Bean处理器,然后拦截bean创建。
registerBeanPostProcessors(beanFactory);

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_13

2.4.2.4、org.springframework.context.support.AbstractApplicationContext#registerBeanPostProcessors

然后我们进入registerBeanPostProcessors方法中,看一下其核心实现,她就是调用了 PostProcessorRegistrationDelegate的registerBeanPostProcessors(beanFactory, this)静态方法。代码如下:

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_14


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默认的后置处理器和我们自定义的后置处理器,具体如下)。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_15


接着我们继续看下去,发现他执行了,下面这行代码去添加一个beanPostProcessor,

beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));具体意思如下:


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_16

然后我们我们可以继续看到其下面有四行代码,如下:


//实现了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


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_17

我们可以自行查看一下org.springframework.aop.config.internalAutoProxyCreator的Bean名称的组件,即是AnnotationAwareAspectJAutoProxyCreator,他的底层类ProxyProcessorSupport实现了Ordered,所以他最终会进入到orderedPostProcessorNames这个list中,代码如下:


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_18

接着他会按照以下顺序是去执行注册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

就会执行到我们这个部分要讲的核心代码了,这段代码有点长,我们直接看核心,在这段代码中有个函数表达式,关于函数表达式的执行顺序,大家可以看一下下面的数字,他会按照0-4执行。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_19

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_20


省略代码来看就是下面:


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();也就是下面截图的代码那

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_21


2.4.2.8、org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean

接着debug他就会到AbstractBeanFactory的doGetBean()方法中,我们可以见名思意发现他就是创建Bean的,也就是说如果getSingleton获取不到Bean的话,我们就通过createBean创建Bean。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_22


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方法


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_23

2.4.2.10、org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

然后当他执行到doCreateBean()方法,准备创建Bean的时候,这个方法会做很多事情,比如Bean的实例化,Bean的属性填充,Bean的初始化,销毁等等,但是对于我们这个AnnotationAwareAspectJAutoProxyCreator的后置处理器来说,他是在执行到exposedObject = initializeBean(beanName, exposedObject, mbd);方法,就会处理的,因此我们直接看initializeBean()初始化方法。


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_24

接下来他会进入到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()方法。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_25

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_26


我们上面讲到了他会执行BeanFactoryAware相关的实现类,那么我们是不是可以定位到org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory方法


2.4.2.12、org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#setBeanFactory

他会进入到AbstractAdvisorAutoProxyCreator的setBeanFactory中去设置BeanFactory,然后会执行到initBeanFactory()中,去初始化BeanFactory。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_27


然后就会调到AnnotationAwareAspectJAutoProxyCreator#initBeanFactory中执行以下代码,主要是创建两个类ReflectiveAspectJAdvisorFactory和BeanFactoryAspectJAdvisorsBuilderAdapter,相当于把之前创建的aspectJAdvisorFactory以及beanFactory重新包装了一下。


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_28

因此整个流程就讲完了。


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[])方法中,在其里面调用了如下代码:

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_29


在resolveBeforeInstantiation()方法里面调用了applyBeanPostProcessorsBeforeInstantiation()和applyBeanPostProcessorsAfterInitialization()两个方法。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_30


其内部的逻辑分别是,从而调用了继承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中,就可以发现他的本质就是上面红色那句话。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_31

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_32

2.4.4、AnnotationAwareAspectJAutoProxyCreator的作用是什么呢?

首先我们通过上面的内容可知,在每一个bean创建之前,都会调用**postProcessBeforeInstantiation()**方法,**postProcessAfterInitialization()**方法。所以我们重点看一下AnnotationAwareAspectJAutoProxyCreator的

**postProcessBeforeInstantiation()和postProcessAfterInitialization()**方法。


2.4.4.1、postProcessBeforeInstantiation

我们直接看AbstractAutoProxyCreator的postProcessBeforeInstantiation方法,他是AnnotationAwareAspectJAutoProxyCreator的核心,具体代码如下:


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_33

解析:


1、先获取缓存的key,可以发现如果BeanName为空,就返回BeanClass,BeanName不为空,就判断当前beanClass是否是FactoryBean,是的话就返回&+beanName,不是的话就返回beanName。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_34


2、判断名为targetSourcedBeans的Set集合里面是否包含有这个bean的名称,但是targetSourcedBeans是一个空的集合


2.1、判断当前bean是否在advisedBeans中

advisedBeans:里面保存了所有需要增强的bean的名称

为什么叫需要增强的bean?简单理解就是通过aop切面代理后的bean,列如日志aop类大家应该都熟悉吧。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_35

3、判断当前bean是否是基础类型,或者是否是切面(标注了@Aspect注解的)


3.1、我们可以发现isInfrastructureClass方法中,他执行了两块代码,分别是

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#isInfrastructureClass

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_36

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_37

可以总结出isInfrastructureClass:判断当前bean是否是基础类型,或者是否是切面(标注了@Aspect注解的),其中基础类型涉及的注解有Advice,Pointcut,Advisor,AopInfrastructureBean。

3.2、判断是否需要跳过

在这里首先是调用findCandidateAdvisors()方法找到候选的增强器的集合:所谓的增强器其实就是切面里面的那些通知方法,只不过,在这儿是把通知方法的详细信息包装成了一个Advisor,并将其存放在了一个List集合中,即增强器的集合,即是说,每一个通知方法都会被认为是一个增强器。并且每一个通知方法都是InstantiationModelAwarePointcutAdvisor类型的,并且我们还可以发现是@Aspect修饰的类的aop方法。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_38



判断当前Advisor是否是AspectJPointcutAdvisor这种类型的,如果是,那么返回true。然而在我们这肯定不是,因为都是InstantiationModelAwarePointcutAdvisor类型的,所以不会进,因此会调用super.shouldSkip(beanClass, beanName)


org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_39

org.springframework.aop.framework.autoproxy.AutoProxyUtils#isOriginalInstance,这里会判断当前的beanName是否为空或者beanName的长度不等于beanClass的长度+“.ORIGINAL"的长度,是的话就返回false,不是的话就判断beanName的开始是否等于beanClass的名字和beanName的结束是否等于”.ORIGINAL"。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_40

4、如果是配置类,比如我们前面的章节里面的MainConfig的话,那么3就会返回false,就不会执行if里面的语句。并且下面中TargetSource也会为空,所以postProcessBeforeInstantiation()方法整体会返回null。


因此,我们可以发现,在每次创建bean的时候,都会先调用postProcessBeforeInstantiation()方法,然后再调用postProcessAfterInitialization()方法。


2.4.4.2、postProcessAfterInitialization


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_41

解析(我们还是基于MainConfig来讲):


1、首先我们看一下传入当前方法的Bean是否为空,我们很清晰的可以发现bean就是ManConfig,所以他要进入if。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_42


2、先获取缓存的key,可以发现如果BeanName为空,就返回BeanClass,BeanName不为空,就判断当前beanClass是否是FactoryBean,是的话就返回&+beanName,不是的话就返回beanName。所以对于我们当前来说,他返回的就是mainConfig。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_43


3、判断名为earlyProxyReferences的Set集合里面是否包含当前bean,在该Set集合里面我们可以看到之前已经代理过了什么,目前该Set集合是一个空集合。因为当前earlyProxyReferences是肯定不包括,所以会进入到wrapIfNecessary(bean, beanName, cacheKey)。


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_44

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注解的)


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_45

4.4.1、我们可以发现isInfrastructureClass方法中,他执行了两块代码,分别是


org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#isInfrastructureClass


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_46

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#isInfrastructureClass

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_47


可以总结出isInfrastructureClass:判断当前bean是否是基础类型,或者是否是切面(标注了@Aspect注解的),其中基础类型涉及的注解有Advice,Pointcut,Advisor,AopInfrastructureBean。


4.4.2、判断是否需要跳过


在这里首先是调用findCandidateAdvisors()方法找到候选的增强器的集合:所谓的增强器其实就是切面里面的那些通知方法,只不过,在这儿是把通知方法的详细信息包装成了一个Advisor,并将其存放在了一个List集合中,即增强器的集合,即是说,每一个通知方法都会被认为是一个增强器。并且每一个通知方法都是InstantiationModelAwarePointcutAdvisor类型的,并且我们还可以发现是@Aspect修饰的类的aop方法。


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_48


判断当前Advisor是否是AspectJPointcutAdvisor这种类型的,如果是,那么返回true。然而在我们这肯定不是,因为都是InstantiationModelAwarePointcutAdvisor类型的,所以不会进,因此会调用super.shouldSkip(beanClass, beanName)


org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_49


org.springframework.aop.framework.autoproxy.AutoProxyUtils#isOriginalInstance,这里会判断当前的beanName是否为空或者beanName的长度不等于beanClass的长度+“.ORIGINAL"的长度,是的话就返回false,不是的话就判断beanName的开始是否等于beanClass的名字和beanName的结束是否等于”.ORIGINAL"。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_50

4.4.3、如果上面两条件有一个是true的话,就设置增强advisedBeans的map为cacheKey,false。然后返回bean。


4.5、获取当前bean的所有增强器,调用getAdvicesAndAdvisorsForBean()方法获取当前bean的所有增强器,也就是那些通知方法,最终封装成这样一个Object[] specificInterceptors数组。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_51


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的这个类型的所有的可用的增强器

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_52


4.5.1.1.1.1、进入其中就可以发现,其第一步是获取候选的所有增强器,也就是@Aspect的各种定义的通知类型方法(前置,后置,环绕,后置。。。)

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_53


4.5.1.1.1.2、找到候选的所有增强器,也就是说是来找哪些通知方法是需要切入到当前bean的目标方法中的。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_54

4.5.1.1.1.2.1、org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply,它是用AopUtils工具类来找到所有能用的增强器(通知方法)的。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_55


4.5.1.1.1.2.1.1、然后我们可以进入到org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply,看一下其核心源码,本质上就是表达式匹配所有可用的增强器,从而把他添加到一个list中,并返回

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_56

最后一个canApply的源码。


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_57

          - 4.5.1.1.1.3、如果eligibleAdvisors不为空,就会进行排序,也就是说调用哪些通知方法,是有顺序的。然后进行返回。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_58

- 4.5.1.2、如果findEligibleAdvisors(beanClass, beanName)返回为空,就返回null,也就是空Object[],返回就正常返回。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_59

- 4.5.2、现在specificInterceptors的Object[]数组里面已经具有了那些指定好的增强器,这些增强器其实就是要拦截目标方法执行的。

- 4.5.3、总结一下

- 找到候选的所有增强器,也就是说是来找哪些通知方法是需要切入到当前bean的目标方法中的

- 获取到能在当前bean中使用的增强器

- 给增强器排序


4.6、保存当前bean在advisedBeans中,表示这个当前bean已经被增强处理了


【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_60

接着进入到createProxy中,也就是最核心的创建代理的方法,具体代码流程如下:

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#buildProxy,这里我们只看最后一步,其他代码都是一些过滤。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_List_61


proxyFactory.getProxyClass(classLoader),一般情况下不会调用当前方法,因此我们可以看一下前面传进来的classOnly他是false,重点看下面这个。

proxyFactory.getProxy(classLoader)),具体代码如下,我们直接看一下getProxy的实现。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_后端_62

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_63


我们可以发现getProxy会有两个实现,一个是jdk,一个是cglib,spring会分析如果当前类是有实现接口的,那么就使用jdk来创建动态代理,如果当前类没有实现接口,此时jdk是没法创建动态代理的,那么自然就得使用cglib来创建动态代理了。对于我们当前来说是cglib,spring也可以设置所有的代理都用cglib,只需要配置类开启@EnableAspectJAutoPrxy(proxyTargetClass = true),具体的更详细的可以自行百度。

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_spring_64

4.7、设置代理类,返回

【Spring【AOP】】——21、@EnableAspectJAutoProxy注解详解?_java_65

总结:


获取所有增强器,所谓的增强器就是切面里面的那些通知方法。


然后再把这些增强器保存到代理工厂(即proxyFactory)中。


为当前组件创建代理对象,并且会有两种形式的代理对象,它们分别如下,最终Spring会自动决定,是为当前组件创建jdk的动态代理,还是创建cglib的动态代理。


一种是JdkDynamicAopProxy这种形式的,即jdk的动态代理

一种是ObjenesisCglibAopProxy这种形式的,即cglib的动态代理


【版权声明】本文内容来自摩杜云社区用户原创、第三方投稿、转载,内容版权归原作者所有。本网站的目的在于传递更多信息,不拥有版权,亦不承担相应法律责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@moduyun.com

  1. 分享:
最后一次编辑于 2023年11月08日 0

暂无评论

推荐阅读
  2Vtxr3XfwhHq   2024年05月17日   55   0   0 Java
  Tnh5bgG19sRf   2024年05月20日   110   0   0 Java
  8s1LUHPryisj   2024年05月17日   46   0   0 Java
  aRSRdgycpgWt   2024年05月17日   47   0   0 Java
4mHcszqpqM94