Spring之AOP源码理解,Spring4.3.12.RELEASE版本

本文深入探讨了Spring AOP的实现原理,从@EnableAspectJAutoProxy注解开始,详细介绍了AspectJAutoProxyRegistrar如何给Spring容器注册组件。接着,通过调试分析了AOP的源码,重点讲解了AnnotationAwareAspectJAutoProxyCreator如何作为后置处理器和BeanFactory工作,并在Bean创建过程中发挥作用。最后,通过断点调试展示了AOP如何拦截和执行方法,揭示了AOP代理对象的生成及调用流程。
摘要由CSDN通过智能技术生成

1、AOP原理,核心从@EnableAspectJAutoProxy注解进行入手研究。

AOP整个功能要起作用,都要从@EnableAspectJAutoProxy注解开始研究的。

@EnableAspectJAutoProxy注解导入这个组件@Import(AspectJAutoProxyRegistrar.class)。给Spring容器导入AspectJAutoProxyRegistrar这个组件。利用AspectJAutoProxyRegistrar自定义给容器中注册bean。

这个AspectJAutoProxyRegistrar组件类,实现了ImportBeanDefinitionRegistrar这个接口。

这个ImportBeanDefinitionRegistrar接口的registerBeanDefinitions方法,可以给容器中注册自定义的组件,给这个BeanDefinitionRegistry自定义注册组件,BeanDefinitionRegistry是bean定义的注册类信息。把所有需要添加到容器中的bean。

注意:组件注册@Import注解结合ImportBeanDefinitionRegistrar使用,ImportBeanDefinitionRegistrar是一个接口,规定方法registerBeanDefinitions,返回值是空void。通过调用该方法自己给容器中添加组件。importingClassMetadata是当前类的注解信息,registry是bean定义的注册类,使用registry给容器注册一个bean实例。

2、AOP源码,打断点debug分析,如下所示:

调用工具类AopConfigUtils的工具方法registerAspectJAnnotationAutoProxyCreatorIfNecessary,如果需要的话注册这个组件。

Step Into(F5)进去,观察给Spring容器中注入了什么。将AnnotationAwareAspectJAutoProxyCreator类传进去。

Step Into(F5)进去,registerOrEscalateApcAsRequired方法是注册或者升级一下,将AnnotationAwareAspectJAutoProxyCreator类传进去。该registerOrEscalateApcAsRequired方法传进去AnnotationAwareAspectJAutoProxyCreator这个类型。

判断容器中是否包含internalAutoProxyCreator这个类型的bean组件。

判断容器中如果不包含internalAutoProxyCreator这个类型的bean组件。创建这个类的AnnotationAwareAspectJAutoProxyCreator定义信息。

利用registry将beanDefinition这个bean的定义即创建AnnotationAwareAspectJAutoProxyCreator,这个bean的名称就叫做internalAutoProxyCreator。最后将bean的信息注册到BeanDefinitionRegistry。

AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

第一步做完以后相当于给容器注册了一个这个bean对象。internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator。

流程如是,@EnableAspectJAutoProxy引入了@Import(AspectJAutoProxyRegistrar.class)。@Import(AspectJAutoProxyRegistrar.class),这个@Import导入给容器注入了AnnotationAwareAspectJAutoProxyCreator(注解自动代理创建器)对象实例。

Step Over(F6)继续向下走,如下所示:

获取到注解@EnableAspectJAutoProxy的内容信息。

判断获取到注解@EnableAspectJAutoProxy的内容信息enableAspectJAutoProxy,进行判断,然后进行一系列操作。

3、容器中注册的组件AnnotationAwareAspectJAutoProxyCreator。AOP功能的核心。AOP原理,主要看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能是什么?

1 AnnotationAwareAspectJAutoProxyCreator。类继承关系,如下所示:
2     -> extends  AspectJAwareAdvisorAutoProxyCreator        
3         -> extends  AbstractAdvisorAutoProxyCreator
4             -> extends  AbstractAutoProxyCreator
5                 -> implements  SmartInstantiationAwareBeanPostProcessor(bean的后置处理器),BeanFactoryAware(设置bean工厂的)
6                     -> extendsInstantiationAwareBeanPostProcessor
7                         -> extendsBeanPostProcessor
8 注意:InstantiationAwareBeanPostProcessor重点关注后置处理器的工作(后置处理器在bean初始化完成前后做一些处理事情)。                
9 BeanFactoryAware自动装配BeanFactory工厂。

AOP原理AnnotationAwareAspectJAutoProxyCreator分析,AnnotationAwareAspectJAutoProxyCreator实现了后置处理器和BeanFactory工厂的功能。但是AnnotationAwareAspectJAutoProxyCreator作为后置处理器做了哪些工作,作为BeanFactory工厂做了那些工作。

打断点的技巧,将断点打到AbstractAutoProxyCreator这个类上面,实现了后置处理器和BeanFactory工厂接口的。如果不是重载或者重写的肯定是此类自己定义的方法,这个可以先不管。

1 AbstractAutoProxyCreator.setBeanFactory();第一个断点,这个是实现了BeanFactory工厂的。
2 AbstractAutoProxyCreator.postProcessBeforeInstantiation();第二个断点,这个是和后置处理器有关的方法。
3 AbstractAutoProxyCreator.postProcessAfterInitialization();第三个断点,这个是和后置处理器有关的方法。

然后分析AbstractAutoProxyCreator类的子类AbstractAdvisorAutoProxyCreator

1 AbstractAdvisorAutoProxyCreator.setBeanFactory();子类重写了父类的setBeanFactory()方法。第四个断点,这个是实现了BeanFactory工厂的。
2 AbstractAdvisorAutoProxyCreator.initBeanFactory();setBeanFactory()这个方法调用了initBeanFactory()方法。

然后分析AbstractAdvisorAutoProxyCreator类的子类AspectJAwareAdvisorAutoProxyCreator。由于AspectJAwareAdvisorAutoProxyCreator类未对后置处理器和BeanFactory工厂做重写操作,可以先不看。

然后分析AspectJAwareAdvisorAutoProxyCreator类的子类AnnotationAwareAspectJAutoProxyCreator

1 AnnotationAwareAspectJAutoProxyCreator.initBeanFactory();此方法重写父类的AbstractAdvisorAutoProxyCreator.initBeanFactory()方法。第五个断点,这个是实现了BeanFactory工厂的。

4、将自己的目标类mathCalculator()、切面类logAspect()都打好断点开始进行调试。

 1 package com.bie.config;
 2 
 3 import org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator;
 4 import org.springframework.aop.framework.ProxyProcessorSupport;
 5 import org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator;
 6 import org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator;
 7 import org.springframework.beans.factory.Aware;
 8 import org.springframework.beans.factory.BeanFactoryAware;
 9 import org.springframework.beans.factory.config.BeanPostProcessor;
10 import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
11 import org.springframework.beans.factory.config.SmartInstantiationAwareBeanPostProcessor;
12 import org.springframework.context.annotation.Bean;
13 import org.springframework.context.annotation.Configuration;
14 import org.springframework.context.annotation.EnableAspectJAutoProxy;
15 
16 import com.bie.aop.LogAspect;
17 import com.bie.aop.MathCalculator;
18 
19 /**
20  * 
21  *
22  * @Title: SpringApplicationConfig.java
23  * @Package com.bie.config
24  * @Description: TODO
25  * @author biehl
26  * @date 2019年12月9日
27  * @version V1.0
28  * 
29  * 
30  *          1、AOP原理,核心从@EnableAspectJAutoProxy注解进行入手研究。
31  *              AOP整个功能要起作用,都要从@EnableAspectJAutoProxy注解开始研究的。
32  *          2、@EnableAspectJAutoProxy注解研究步骤。 @EnableAspectJAutoProxy注解,导入了@Import(AspectJAutoProxyRegistrar.class),给容器中导入了AspectJAutoProxyRegistrar。
33  *              利用AspectJAutoProxyRegistrar自定义给容器中注册bean。
34  *             3、第一步@EnableAspectJAutoProxy引入了@Import(AspectJAutoProxyRegistrar.class)。
35  *                 @Import(AspectJAutoProxyRegistrar.class),这个@Import导入给容器注入了AnnotationAwareAspectJAutoProxyCreator(注解AspectJ自动代理创建器)对象实例。
36  *             4、容器中注册的组件AnnotationAwareAspectJAutoProxyCreator。AOP功能的核心。
37  *                 AOP原理,主要看给容器中注册了什么组件,这个组件什么时候工作,这个组件的功能是什么?
38  *             5、AnnotationAwareAspectJAutoProxyCreator。类继承关系,如下所示:
39  *                 -> extends AspectJAwareAdvisorAutoProxyCreator        
40  *                     -> extends AbstractAdvisorAutoProxyCreator
41  *                         -> extends AbstractAutoProxyCreator
42  *                             -> implements SmartInstantiationAwareBeanPostProcessor(bean的后置处理器), BeanFactoryAware(设置bean工厂的)
43  *                                 -> extends InstantiationAwareBeanPostProcessor
44  *                                     -> extends BeanPostProcessor
45  *                 注意:InstantiationAwareBeanPostProcessor重点关注后置处理器的工作(后置处理器在bean初始化完成前后做一些处理事情)。                
46  *                     BeanFactoryAware自动装配BeanFactory工厂。
47  *             6、打断点的技巧,将断点打到AbstractAutoProxyCreator这个类上面,实现了后置处理器和BeanFactory工厂接口的。
48  *                 AbstractAutoProxyCreator.setBeanFactory();第一个断点,这个是实现了BeanFactory工厂的。
49  *                 AbstractAutoProxyCreator.postProcessBeforeInstantiation();第二个断点,这个是和后置处理器有关的方法。
50  *                 AbstractAutoProxyCreator.postProcessAfterInitialization();第三个断点,这个是和后置处理器有关的方法。
51  *                 如果不是重载或者重写的肯定是此类自己定义的方法,这个可以先不管。
52  *             7、然后分析AbstractAutoProxyCreator类的子类AbstractAdvisorAutoProxyCreator。
53  *                 AbstractAdvisorAutoProxyCreator.setBeanFactory();子类重写了父类的setBeanFactory()方法。    
54  *                 AbstractAdvisorAutoProxyCreator.initBeanFactory();setBeanFactory()这个方法调用了initBeanFactory()方法。
55  *             8、然后分析AbstractAdvisorAutoProxyCreator类的子类AspectJAwareAdvisorAutoProxyCreator。            
56  *             9、然后分析AspectJAwareAdvisorAutoProxyCreator类的子类AnnotationAwareAspectJAutoProxyCreator。
57  *                 AspectJAwareAdvisorAutoProxyCreator.initBeanFactory();此方法重写父类的AbstractAdvisorAutoProxyCreator.initBeanFactory()方法。
58  *             10、将自己的目标类mathCalculator()、切面类logAspect()都打好断点开始进行调试。 
59  * 
60  * 
61  */
62 // @Configuration告诉Spring这是一个配置类,相当于bean.xml配置文件。
63 @Configuration
64 @EnableAspectJAutoProxy
65 public class SpringApplicationConfig16 {
66 
67     /**
68      * 将目标类加入到容器中
69      * 
70      * @return
71      */
72     @Bean
73     public MathCalculator mathCalculator() {
74         return new MathCalculator();
75     }
76 
77     /**
78      * 将切面类加入到容器中
79      * 
80      * @return
81      */
82     @Bean
83     public LogAspect logAspect() {
84         return new LogAspect();
85     }
86 
87 }

各个类继承关系图,如下所示:

AOP原理,注册AnnotationAwareAspectJAutoProxyCreator。如下所示:

打好断点以后,先进到这里,AbstractAdvisorAutoProxyCreator类,如下所示:

根据eclipse工具显示的Debug方法栈,先从头开始分析一下,第一步创建IOC容器,调用AnnotationConfigApplicationContext()方法的有参构造器,AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(SpringApplicationConfig16.class);传入主配置类SpringApplicationConfig16参数。

分析方法栈的下一步,创建AnnotationConfigApplicationContext有参构造器方法。

this();无参构造器创建对象。自己可以点进去看一下。
register(annotatedClasses);将配置类注册进去,注册配置类。
refresh();调用容器刷新方法,刷新容器。刷新容器将所有bean创建出来,所有的功能都做好,像初始化容器一样。

refresh();刷新容器是如何做的呢,点击方法栈的下一步。如下所示:

registerBeanPostProcessors(beanFactory);注册bean的后置处理器。翻译,Register bean processors that intercept bean creation。注册bean的后置处理器拦截bean的创建。

点击方法栈的下一步,后置处理器的注册逻辑,是怎么样的呢?

点击方法栈的下一步,执行如下所示:

可以看下BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);上面执行的过程和结果。

首先获取到IOC容器中已经定义的需要创建对象的所有BeanPostProcessor。已定义的后置处理器是由于创建IOC容器的时候,传入配置类,配置类添加了@EnableAspectJAutoProxy注解,该注解向容器中注入了后置处理器AnnotationAwareAspectJAutoProxyCreator。容器中也默认定义了一些后置处理器。

1 org.springframework.context.annotation.internalAutowiredAnnotationProcessor, // 处理Autowired自动注解的后置处理器
2 org.springframework.context.annotation.internalRequiredAnnotationProcessor, // 处理Required必填注解的后置处理器
3 org.springframework.context.annotation.internalCommonAnnotationProcessor, // 处理Common普通注解的后置处理器
4 org.springframework.aop.config.internalAutoProxyCreator// internalAutoProxyCreator(注解AspectJ自动代理创建器)这个就是自己第一步执行注入到IOC容器的后置处理器。按照bean定义进行创建对象,创建AnnotationAwareAspectJAutoProxyCreator对象。

如图所示:

所谓的注册是什么呢,org.springframework.aop.config.internalAutoProxyCreator,我们即将要创建的internalAutoProxyCreator,其实就是AnnotationAwareAspectJAutoProxyCreator。其实AnnotationAwareAspectJAutoProxyCreator是实现Ordered这个接口的。

方法registerBeanPostProcessors(),注册后置处理器的步骤如下所示:

 1 // 注册bean的后置处理器
 2 public static void registerBeanPostProcessors(
 3         ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
 4     
 5     // 获取到IOC容器中Bean实例对象。调用getBeanNamesForType()方法。
 6     // 按照类型进行获取到IOC容器中所有需要创建的后置处理器。
 7     // 首先获取到IOC容器中已经定义的需要创建对象的所有BeanPostProcessor。
 8     // 已定义的后置处理器是由于创建IOC容器的时候,传入配置类,配置类添加了@EnableAspectJAutoProxy注解,
 9     // 该注解向容器中注入了后置处理器AnnotationAwareAspectJAutoProxyCreator。容器中也默认定义了一些后置处理器。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值