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

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     String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
11 
12     // Register BeanPostProcessorChecker that logs an info message when
13     // a bean is created during BeanPostProcessor instantiation, i.e. when
14     // a bean is not eligible for getting processed by all BeanPostProcessors.
15     int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
16     // 给容器中加入别的后置处理器BeanPostProcessor。
17     beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
18 
19     // Separate between BeanPostProcessors that implement PriorityOrdered,
20     // Ordered, and the rest.
21     // 分离BeanPostProcessors,实现了PriorityOrdered接口、Ordered接口、原生的为实现接口的。
22     List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
23     List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>();
24     List<String> orderedPostProcessorNames = new ArrayList<String>();
25     List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
26     for (String ppName : postProcessorNames) {
27         if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
28             BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
29             priorityOrderedPostProcessors.add(pp);
30             if (pp instanceof MergedBeanDefinitionPostProcessor) {
31                 internalPostProcessors.add(pp);
32             }
33         }
34         else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
35             orderedPostProcessorNames.add(ppName);
36         }
37         else {
38             nonOrderedPostProcessorNames.add(ppName);
39         }
40     }
41 
42     // First, register the BeanPostProcessors that implement PriorityOrdered.
43     // 第一步、优先注册实现了PriorityOrdered接口的BeanPostProcessor。
44     sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
45     registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
46 
47     // Next, register the BeanPostProcessors that implement Ordered.
48     // 第二步、再给容器中注册实现了Ordered接口的BeanPostProcessor。
49     List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>();
50     for (String ppName : orderedPostProcessorNames) {
51         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
52         orderedPostProcessors.add(pp);
53         if (pp instanceof MergedBeanDefinitionPostProcessor) {
54             internalPostProcessors.add(pp);
55         }
56     }
57     sortPostProcessors(orderedPostProcessors, beanFactory);
58     registerBeanPostProcessors(beanFactory, orderedPostProcessors);
59 
60     // Now, register all regular BeanPostProcessors.
61     // 第三步、再给容器注册普通的,注册没有实现优先级接口的BeanPostProcessor。
62     List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>();
63     // 所谓的注册是什么呢,org.springframework.aop.config.internalAutoProxyCreator,
64     // 我们即将要创建的internalAutoProxyCreator,其实就是AnnotationAwareAspectJAutoProxyCreator。
65     for (String ppName : nonOrderedPostProcessorNames) {
66         // ppName = org.springframework.aop.config.internalAutoProxyCreator,获取到BeanPostProcessor的名称ppName,然后从beanFactory中进行获取。
67         BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
68         nonOrderedPostProcessors.add(pp);
69         if (pp instanceof MergedBeanDefinitionPostProcessor) {
70             internalPostProcessors.add(pp);
71         }
72     }
73     registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
74 
75     // Finally, re-register all internal BeanPostProcessors.
76     // 最后,注册所有的BeanPostProcessors
77     sortPostProcessors(internalPostProcessors, beanFactory);
78     registerBeanPostProcessors(beanFactory, internalPostProcessors);
79 
80     // Re-register post-processor for detecting inner beans as ApplicationListeners,
81     // moving it to the end of the processor chain (for picking up proxies etc).
82     beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
83 }

点击方法栈的下一步从beanFactory.getBean(ppName, BeanPostProcessor.class);获取bean对象。

点击方法栈的下一步,sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {.....} ,获取单实例的bean。IOC容器中第一次不会存在该Bean实例的。

点击方法栈的下一步,获取不到,会调用getObject()方法,singletonObject = singletonFactory.getObject(); 获取到Object对象。

点击方法栈的下一步 return createBean(beanName, mbd, args);创建Bean实例。如果BeanPostProcessor获取不到就创建Bean对象,注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存到容器中即可。

点击方法栈的下一步,那么是如何创建org.springframework.aop.config.internalAutoProxyCreator这个BeanPostProcessor的,即AnnotationAwareAspectJAutoProxyCreator该对象。

创建Bean的方法如下所示:

点击方法栈的下一步,创建完毕Bean实例以后,就需要进行初始化操作了。

populateBean(beanName, mbd, instanceWrapper);是属性赋值的操作。给Bean的各种属性赋值。

initializeBean(beanName, exposedObject, mbd);初始化Bean,初始化Bean十分重要,因为后置处理器BeanPostProcessor就是在Bean初始化的前后进行工作的。

点击方法栈的下一步,如何进行Bean的初始化操作呢,如下所示:

invokeAwareMethods(beanName, bean);判断是否是Aware接口,是否是BeanNameAware接口、BeanClassLoaderAware接口、BeanFactoryAware接口的类型,相当于是处理Aware接口的方法回调。

beanName=org.springframework.aop.config.internalAutoProxyCreator。

wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);返回一个包装的Bean。应用后置处理器的postProcessBeforeInitialization。

拿到所有的后置处理器,然后调用后置处理器的postProcessBeforeInitialization方法,beanProcessor.postProcessBeforeInitialization。后置处理器的调用是在这里哦。后置处理器初始化之前的调用在这里哦。

invokeInitMethods(beanName, wrappedBean, mbd);执行自定义的初始化方法。 

wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);执行后置处理器postProcessAfterInitialization。

拿到所有的后置处理器,然后调用后置处理器的postProcessBeforeInitialization方法,beanProcessor.postProcessBeforeInitialization。后置处理器的调用是在这里哦。后置处理器初始化之后的调用在这里哦。 

代码如下所示:

 1 // 初始化Bean的方法
 2 protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
 3     if (System.getSecurityManager() != null) {
 4         AccessController.doPrivileged(new PrivilegedAction<Object>() {
 5             @Override
 6             public Object run() {
 7                 invokeAwareMethods(beanName, bean);
 8                 return null;
 9             }
10         }, getAccessControlContext());
11     }
12     else {
13         // 处理Aware接口的方法回调。
14         invokeAwareMethods(beanName, bean);
15     }
16 
17     Object wrappedBean = bean;
18     if (mbd == null || !mbd.isSynthetic()) {
19         // 应用后置处理器的postProcessAfterInitialization
20         wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
21     }
22 
23     try {
24         // 执行自定义的初始化方法。
25         invokeInitMethods(beanName, wrappedBean, mbd);
26     }
27     catch (Throwable ex) {
28         throw new BeanCreationException(
29                 (mbd != null ? mbd.getResourceDescription() : null),
30                 beanName, "Invocation of init method failed", ex);
31     }
32 
33     if (mbd == null || !mbd.isSynthetic()) {
34         // 
35         wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
36     }
37     return wrappedBean;
38 }

点击方法栈的下一步,bean 实现了BeanFactoryAware接口,bean instanceof BeanFactoryAware,所以执行((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);

点击方法栈的下一步,哈哈哈,进入了AbstractAdvisorAutoProxyCreator.setBeanFactory()方法了,有木有很熟悉了。

5、点击Step Over(F6)。进入了AbstractAutoProxyCreator.setBeanFactory()方法了,父类的setBeanFactory()方法。

第一步是调用父类的 setBeanFactory()方法。点击Step Over(F6),走到initBeanFactory((ConfigurableListableBeanFactory) beanFactory);

点击Step Into(F5),调用到了AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()方法。这个initBeanFactory()方法创建了ReflectiveAspectJAdvisorFactory反射的AspectJ通知工厂,BeanFactoryAspectJAdvisorsBuilderAdapter通知构建的适配器,包装了beanFactory和this.aspectJAdvisorFactory。

以上全部过程是创建和注册AnnotationAwareAspectJAutoProxyCreator(后置处理器)的过程,将这个后置处理器创建对象放入到IOC容器中,那么,其他组件在创建对象的时候,任何组件在创建Bean的实例,都会调用populateBean给bean的各种属性赋值,initializeBean初始化Bean(初始化前后都会有后置处理器的作用),所以在以后创建其他组件的时候,AnnotationAwareAspectJAutoProxyCreator可以拦截到这些创建过程。AnnotationAwareAspectJAutoProxyCreator作为后置处理器,接下来都做了什么呢? 

6、AOP原理,AnnotationAwareAspectJAutoProxyCreator执行时机。Debug启动,打的断点还是之前的哦。

直接Resume(F8) 放行,下一个断点。AbstractAdvisorAutoProxyCreator抽象类继承了AbstractAutoProxyCreator抽象类。调用了父类AbstractAutoProxyCreator的setBeanFactory()方法。

直接点击两次Resume(F8) 放行,下一个断点。

注意,记得区别:

  后置处理器BeanPostProcessor接口的postProcessBeforeInitialization()方法、postProcessAfterInitialization()方法。

  后置处理器InstantiationAwareBeanPostProcessor接口的postProcessBeforeInstantiation()方法、postProcessAfterInstantiation()方法。

继承和实现关系如下所示:

AbstractAutoProxyCreator抽象类实现了SmartInstantiationAwareBeanPostProcessor接口,

SmartInstantiationAwareBeanPostProcessor接口继承了InstantiationAwareBeanPostProcessor接口,

InstantiationAwareBeanPostProcessor接口继承了BeanPostProcessor接口。

探索一下,为什么来到这里呢,AbstractAutoProxyCreator.postProcessBeforeInstantiation()。

finishBeanFactoryInitialization(beanFactory);完成BeanFactory初始化工作,创建剩下的单实例Bean对象。

registerBeanPostProcessors(beanFactory);注册bean的后置处理器。注意,是这个方法先被调用,才调用的finishBeanFactoryInitialization(beanFactory);

点击方法栈的下一步,再次点击方法栈的下一步, 调用获取Bean,getBean(beanName);

List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);,beanDefinitionNames是IOC容器中所有定义的Bean实例的名称。然后进行下面的for循环操作。

finishBeanFactoryInitialization(beanFactory);完成BeanFactory初始化工作的第一步,遍历获取容器中所有的Bean,依次创建对象getBean(beanName);

点击方法栈的下一步,getBean(beanName);调用了doGetBean(name, null, null, false);方法。

点击方法栈的下一步,第二步,创建bean实例对象,doGetBean(name, null, null, false);方法调用了getSingleton()获取单实例Bean实例。

查看上面的步骤,Object sharedInstance = getSingleton(beanName);先从缓存中获取当前的bean,如果可以获取到,说明bean是之前被创建过的,直接使用,否则再进行创建,只要创建的bean都会被缓存起来的。

点击方法栈的下一步,再次点击方法栈的下一步,createBean()创建bean。

注意:createBean()创建bean,AnnotationAwareAspectJAutoProxyCreator会在任何bean实例创建之前先尝试返回bean实例。

创建Bean,Object bean = resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation。希望后置处理器在此能返回一个代理对象。给后置处理器一个机会,来返回代理对象,而替代我们创建的目标的bean实例。

如果能返回代理对象就使用,如果不能就继续调用下面的创建bean方法doCreateBean(beanName, mbdToUse, args);真正的创建一个bean实例的过程。

doCreateBean()才是真正的创建bean实例的哦。createBeanInstance()创建bean实例方法。

向下巴拉巴拉, populateBean(beanName, mbd, instanceWrapper);属性赋值,initializeBean(beanName, exposedObject, mbd);初始化bean实例。

点击initializeBean(beanName, exposedObject, mbd);方法,进去以后和上面介绍的都一致了,如下所示:

点击方法栈的下一步,其实是先执行,Object bean = resolveBeforeInstantiation(beanName, mbdToUse);后置处理器先尝试返回对象。

applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);方法,是获取到所有的后置处理器,如果是InstantiationAwareBeanPostProcessor这个类型的,就执行postProcessBeforeInstantiation(beanClass, beanName);

而这方法,其实就是InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()的方法哦。

注意:千万记得区分。

BeanPostProcessor是在Bean对象创建完成初始化前后调用的。
InstantiationAwareBeanPostProcessor是在创建Bean实例之前先尝试使用后置处理器返回对象的。在任何Bean实例创建之前AbstractAutoProxyCreator.postProcessBeforeInstantiation()这个方法。

 1 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
 2         Object bean = null;
 3         if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
 4             // Make sure bean class is actually resolved at this point.
 5             if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
 6                 Class<?> targetType = determineTargetType(beanName, mbd);
 7                 if (targetType != null) {
 8                     bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
 9                     if (bean != null) {
10                         bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
11                     }
12                 }
13             }
14             mbd.beforeInstantiationResolved = (bean != null);
15         }
16         return bean;
17     }

如下所示:

createBean()创建bean,AnnotationAwareAspectJAutoProxyCreator会在任何bean实例创建之前先尝试返回bean实例。

点击方法栈的下一步。

此时,就已经到了,刚才看到的方法postProcessBeforeInstantiation()。

AnnotationAwareAspectJAutoProxyCreator在所有Bean创建之前有一个拦截,因为是继承了InstantiationAwareBeanPostProcessor这个后置处理器,所以会调用AbstractAutoProxyCreator.postProcessBeforeInstantiation()方法。

1 public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
2         implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
3 
4 .......
5 }

如下所示:

6、AOP原理,创建AOP代理。那么AbstractAutoProxyCreator.postProcessBeforeInstantiation()这个方法都做了什么呢。

AnnotationAwareAspectJAutoProxyCreator是InstantiationAwareBeanPostProcessor这种后置处理器,这种后置处理器的作用就是在每一个Bean创建之前调用postProcessBeforeInstantiation()方法。

重启Debug,直接Resume(F8) 放行,走到AbstractAutoProxyCreator.postProcessBeforeInstantiation()这个方法。由于是循环创建bean实例,每一个Bean创建之前都会执行postProcessBeforeInstantiation()、postProcessAfterInitialization()。

1 下面这几个直接Resume(F8)跳过即可。
2 class org.springframework.context.event.EventListenerMethodProcessor
3 class org.springframework.context.event.DefaultEventListenerFactory
4 class com.bie.config.SpringApplicationConfig16$$EnhancerBySpringCGLIB$$c2258ea4

直接找到,我们注入到bean容器中的实例对象。

现在只关心MathCalculator、LogAspect,我们自己创建的bean实例。分析,如下所示:

 1 @Override
 2 public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
 3     // 获取到bean实例的名称mathCalculator
 4     Object cacheKey = getCacheKey(beanClass, beanName);
 5     
 6     // 判断beanName是null或者targetSourcedBeans不包含beanName
 7     if (beanName == null || !this.targetSourcedBeans.contains(beanName)) {
 8         // 已经增强的Bean是否包含cacheKey的值。判断当前bean是否在advisedBeans(里面保存了所有需要增强的bean)中。
 9         // 什么是需要增强的bean呢,就是我们自己定义的业务逻辑MathCalculator、LogAspect。需要切面来切的。
10         if (this.advisedBeans.containsKey(cacheKey)) {
11             return null;
12         }
13         // isInfrastructureClass(beanClass)判断当前bean是否是基础类型的(Advice、Pointcut、Advisor、AopInfrastructureBean)。
14         // Step Info(F5)进去isInfrastructureClass,除了判断是否是基础类型的,还判断是否是切面(标注了@Aspect注解)。
15         // 可以使用Step Info(F5)进去,Step Over(F6)下一步,Step Return(F7)退出来。 
16         
17         // shouldSkip(beanClass, beanName)判断是否需要跳过。Step Info(F5)进去,获取候选的增强器(增强器即切面里面的通知方法)。
18         // List<Advisor> candidateAdvisors封装成了List<Advisor>集合,每一个封装的通知方法的增强器类型是InstantiationModelAwarePointcutAdvisor。
19         // 判断每一个增强器是否是AspectJPointcutAdvisor这种类型的。如果是AspectJPointcutAdvisor这种类型返回true。否则永远返回false。
20         if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
21             this.advisedBeans.put(cacheKey, Boolean.FALSE);
22             return null;
23         }
24     }
25 
26     // Create proxy here if we have a custom TargetSource.
27     // Suppresses unnecessary default instantiation of the target bean:
28     // The TargetSource will handle target instances in a custom fashion.
29     // 判断beanName是否为空
30     if (beanName != null) {
31         // 获取到自定义的TargetSource
32         TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
33         if (targetSource != null) {
34             this.targetSourcedBeans.add(beanName);
35             Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
36             Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
37             this.proxyTypes.put(cacheKey, proxy.getClass());
38             return proxy;
39         }
40     }
41 
42     return null;
43 }

上面运行完以后,直接Resume(F8),直接来自定义配置类创建自己需要的对象了,如下所示:

上面运行完以后,直接Resume(F8),当将自己需要创建的对象创建完毕以后,Resume(F8)直接走到了AbstractAutoProxyCreator.postProcessAfterInitialization()方法。

具体的细节,如下所示:

  1 @Override
  2 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  3     // 如果bean不为null
  4     if (bean != null) {
  5         // 获取到bean实例的名称
  6         Object cacheKey = getCacheKey(bean.getClass(), beanName);
  7         // 如果earlyProxyReferences不包含cacheKey的名称
  8         if (!this.earlyProxyReferences.contains(cacheKey)) {
  9             // 进行包装,如果需要的情况下。给容器中返回当前组件使用cglib增强了的代理对象。
 10             // 以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候代理对象就会执行通知方法流程。
 11             return wrapIfNecessary(bean, beanName, cacheKey);
 12         }
 13     }
 14     return bean;
 15 }
 16 
 17 
 18 // 由上面的wrapIfNecessary(bean, beanName, cacheKey);Step Info(F5)进去。
 19 protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
 20     // 如果beanName不为null,已经增强的Bean是否包含cacheKey的值。判断当前bean是否在advisedBeans(里面保存了所有需要增强的bean)中。
 21     if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
 22         return bean;
 23     }
 24     // 判断当前bean是否在advisedBeans(里面保存了所有需要增强的bean)中。
 25     if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
 26         return bean;
 27     }
 28     // isInfrastructureClass(beanClass)判断当前bean是否是基础类型的(Advice、Pointcut、Advisor、AopInfrastructureBean)。
 29     // shouldSkip(beanClass, beanName)判断是否需要跳过。Step Info(F5)进去,获取候选的增强器(增强器即切面里面的通知方法)。
 30     // List<Advisor> candidateAdvisors封装成了List<Advisor>集合,每一个封装的通知方法的增强器类型是InstantiationModelAwarePointcutAdvisor。
 31     // 判断每一个增强器是否是AspectJPointcutAdvisor这种类型的。如果是AspectJPointcutAdvisor这种类型返回true。否则永远返回false。
 32     if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
 33         this.advisedBeans.put(cacheKey, Boolean.FALSE);
 34         return bean;
 35     }
 36 
 37     // Create proxy if we have advice.创建一个代理对象如果我们有advice。
 38     // 获取当前bean的所有增强器(通知方法),获取当前bean的通知方法和增强器。
 39     Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
 40     // 如果specificInterceptors增强器不为null。增强器其实就是拦截目标方法执行的。
 41     if (specificInterceptors != DO_NOT_PROXY) {
 42         // advisedBeans设置成该bean已经增强了。保存当前bean在advisedBeans中。
 43         this.advisedBeans.put(cacheKey, Boolean.TRUE);
 44         // 重要的一步,如果该bean是需要增强的,创建当前bean的代理对象。
 45         Object proxy = createProxy(
 46                 bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
 47         this.proxyTypes.put(cacheKey, proxy.getClass());
 48         // 返回通过cglib动态代理增强的代理对象。
 49         return proxy;
 50     }
 51 
 52     this.advisedBeans.put(cacheKey, Boolean.FALSE);
 53     return bean;
 54 }
 55 
 56 
 57 
 58 // 由上面的getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);Step Info(F5)进去。
 59 @Override
 60 protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
 61     // 获取到所有的增强器。
 62     List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
 63     // 如果advisors增强器是空的,返回DO_NOT_PROXY = null。
 64     if (advisors.isEmpty()) {
 65         return DO_NOT_PROXY;
 66     }
 67     // 否则返回advisors增强器数组。
 68     return advisors.toArray();
 69 }
 70 
 71 
 72 // 由上面的findEligibleAdvisors(beanClass, beanName);Step Info(F5)进去。
 73 protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
 74     // 获取到候选的增强器。即切面里面自己创建的通知方法。
 75     List<Advisor> candidateAdvisors = findCandidateAdvisors();
 76     // 找到可以应用到自己当前创建的bean的增强器(找到哪些通知方法是需要切入到当前bean方法的)。
 77     // 获取到能在当前bean使用的增强器。
 78     List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
 79     extendAdvisors(eligibleAdvisors);
 80     // 如果增强器不为空
 81     if (!eligibleAdvisors.isEmpty()) {
 82         // 就对这些增强器进行排序操作。
 83         eligibleAdvisors = sortAdvisors(eligibleAdvisors);
 84     }
 85     // 返回这些增强器
 86     return eligibleAdvisors;
 87 }
 88 
 89 
 90 // 由上面的createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));Step Info(F5)进去。
 91 protected Object createProxy(
 92         Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
 93     
 94     // 
 95     if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
 96         AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
 97     }
 98 
 99     // 创建代理对象的工厂
100     ProxyFactory proxyFactory = new ProxyFactory();
101     proxyFactory.copyFrom(this);
102 
103     if (!proxyFactory.isProxyTargetClass()) {
104         if (shouldProxyTargetClass(beanClass, beanName)) {
105             proxyFactory.setProxyTargetClass(true);
106         }
107         else {
108             evaluateProxyInterfaces(beanClass, proxyFactory);
109         }
110     }
111     
112     // 获取到所有这些增强器。所谓的增强器就是这些通知方法。
113     Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
114     // 将增强器advisors保存到proxyFactory代理工厂里面
115     proxyFactory.addAdvisors(advisors);
116     proxyFactory.setTargetSource(targetSource);
117     customizeProxyFactory(proxyFactory);
118 
119     proxyFactory.setFrozen(this.freezeProxy);
120     if (advisorsPreFiltered()) {
121         proxyFactory.setPreFiltered(true);
122     } 
123     
124     // 使用代理工厂创建对象,创建代理对象,Step Info(F5)进去。Spring自动决定使用jdk的动态代理、还是cglib的动态代理。
125     // return new JdkDynamicAopProxy(config);jdk的动态代理。如果类是实现接口的,可以使用jdk可以创建动态代理就使用jdk的动态代理。
126     // return new ObjenesisCglibAopProxy(config);cglib的动态代理。如果类是未实现接口的,jdk不可以可以创建动态代理,可以使用cglib可以创建动态代理就使用cglib的动态代理。
127     return proxyFactory.getProxy(getProxyClassLoader());
128 }

7、AOP原理,获取拦截器链MethodInterceptor。AnnotationAwareAspectJAutoProxyCreator是一个后置处理器,是实现InstantiationAwareBeanPostProcessor这种类型的后置处理器。AnnotationAwareAspectJAutoProxyCreator就是@EnableAspectJAutoProxy这个注解导入到容器中的组件。bean创建前后需要处理,特别是对象创建之后,判断对象是否需要包装,如果业务逻辑组件需要被切入,即需要被增强的组件,就为此组件创建代理对象,此时容器中获取到的组件就是代理对象。执行方法的时候就是代理对象调用该方法的。那么代理对象如何调用该方法呢?目标方法的执行,首先在被调用的目标方法打上断点,如下所示:

此时,直接Resume(F8),跳过这些断点,直接走到你在被调用的目标方法打断点的地方。如下所示:

此时容器中获取到的组件就是代理对象,可以看到确实是CGlib增强后的对象。

容器中保存了组件的代理对象(cglib增强后的对象),这个对象里面保存了详细信息(比如增强器、目标对象断点)。

点击Step Info(F5)进去,CglibAopProxy.intercept()方法,拦截目标方法的执行。

 1 // proxy = com.bie.aop.MathCalculator@7b205dbd
 2 // method = public int com.bie.aop.MathCalculator.div(int,int)
 3 // args = [42, 2] 
 4 // methodProxy = org.springframework.cglib.proxy.MethodProxy@106cc338
 5 @Override
 6 public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
 7     Object oldProxy = null;
 8     boolean setProxyContext = false;
 9     Class<?> targetClass = null;
10     Object target = null;
11     try {
12         if (this.advised.exposeProxy) {
13             // Make invocation available if necessary.
14             oldProxy = AopContext.setCurrentProxy(proxy);
15             setProxyContext = true;
16         }
17         // May be null. Get as late as possible to minimize the time we
18         // "own" the target, in case it comes from a pool...
19         // target就是目标对象。target = com.bie.aop.MathCalculator@7b205dbd
20         target = getTarget();
21         if (target != null) {
22             // targetClass = class com.bie.aop.MathCalculator 
23             targetClass = target.getClass();
24         }
25         // 获取拦截器链,advised就是proxyFactory。根据ProxyFactory对象获取将要执行的目标方法拦截器链。拦截器链,即每一个通知方法又被包装成为了方法拦截器,方法的执行都是利用MethodInterceptor方法拦截器机制。
26 // 目标方法前后要执行,是要执行通知方法的。拦截器链是在说通知方法如何执行的,再来执行目标方法的。 27 List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); 28 Object retVal; 29 // Check whether we only have one InvokerInterceptor: that is, 30 // no real advice, but just reflective invocation of the target. 31 // 如果chain拦截器链是空的,如果没有连接器链 32 if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { 33 // We can skip creating a MethodInvocation: just invoke the target directly. 34 // Note that the final invoker must be an InvokerInterceptor, so we know 35 // it does nothing but a reflective operation on the target, and no hot 36 // swapping or fancy proxying. 37 Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); 38 // 将要跳过创建一个MethodInvocation,直接执行目标对象。如果没有连接器链,直接执行目标方法。 39 retVal = methodProxy.invoke(target, argsToUse); 40 } 41 else { 42 // 否则,如果有拦截器链。如果有连接器链,将需要执行的目标对象、目标方法、连接器链等所有信息传入,创建一个CglibMethodInvocation并且调用proceed()方法。 43 // proxy = com.bie.aop.MathCalculator@7b205dbd, 44 // target = com.bie.aop.MathCalculator@7b205dbd, 45 // method = public int com.bie.aop.MathCalculator.div(int,int), 46 // args = [42, 2], 47 // targetClass = class com.bie.aop.MathCalculator, 48 // chain = 四个通知方法和一个默认的方法, 49 // methodProxy = org.springframework.cglib.proxy.MethodProxy@106cc338 50 // We need to create a method invocation... 51 retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); 52 } 53 // 处理返回值。 54 retVal = processReturnType(proxy, target, method, retVal); 55 return retVal; 56 } 57 finally { 58 if (target != null) { 59 releaseTarget(target); 60 } 61 if (setProxyContext) { 62 // Restore old proxy. 63 AopContext.setCurrentProxy(oldProxy); 64 } 65 } 66 }

如下所示:

点击Step Info(F5)进去MethodCacheKey cacheKey = new MethodCacheKey(method);将方法进行缓存,下次直接使用。

 1 public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, Class<?> targetClass) {
 2     // 常见方法key,cacheKey
 3     MethodCacheKey cacheKey = new MethodCacheKey(method);
 4     // 根据这个cacheKey获取到这个方法
 5     List<Object> cached = this.methodCache.get(cacheKey);
 6     // 如果获取到的方法是空的
 7     if (cached == null) {
 8         // advisorChainFactory = DefaultAdvisorChainFactory,advisor链的工厂,就来获取目标方法的拦截器链。
 9         cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
10                 this, method, targetClass);
11         // 将方法key和方法缓存起来,方便下次使用
12         this.methodCache.put(cacheKey, cached);
13     }
14     // 返回cached
15     return cached;
16 }

如下所示:

点击Step Info(F5)进去将会遍历所有的增强器,将这些增强器封装成Interceptor[],最后放入到interceptorList集合中。interceptorList.addAll(Arrays.asList(interceptors));

 1 @Override
 2 public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
 3         Advised config, Method method, Class<?> targetClass) {
 4 
 5     // This is somewhat tricky... We have to process introductions first,
 6     // but we need to preserve order in the ultimate list.
 7     // 创建一个List集合interceptorList。保存所有得拦截器。已经将集合得长度赋值好config.getAdvisors().length。
 8     // 一个默认得ExposeInvocationInterceptor和4个增强器。
 9     List<Object> interceptorList = new ArrayList<Object>(config.getAdvisors().length);
10     Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
11     boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
12     AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
13     
14     // 遍历每一个增强器。将会遍历所有的增强器,将这些增强器封装成Interceptor[],最后放入到interceptorList集合中。
15     for (Advisor advisor : config.getAdvisors()) {
16         // 判断,如果是切入点的增强器。
17         if (advisor instanceof PointcutAdvisor) {
18             // Add it conditionally.
19             PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
20             if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
21                 // 将增强器advisor包装一下
22                 MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
23                 MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
24                 if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
25                     if (mm.isRuntime()) {
26                         // Creating a new object instance in the getInterceptors() method
27                         // isn't a problem as we normally cache created chains.
28                         for (MethodInterceptor interceptor : interceptors) {
29                             // 将包装的interceptors放到interceptorList集合中
30                             interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
31                         }
32                     }
33                     else {
34                         interceptorList.addAll(Arrays.asList(interceptors));
35                     }
36                 }
37             }
38         } //否则,如果不是切入点的增强器。如果增强器是IntroductionAdvisor这种类型的。
39         else if (advisor instanceof IntroductionAdvisor) {
40             IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
41             if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
42                 // // 将增强器advisor包装一下
43                 Interceptor[] interceptors = registry.getInterceptors(advisor);
44                 // 将包装的interceptors放到interceptorList集合中
45                 interceptorList.addAll(Arrays.asList(interceptors));
46             }
47         } // 否则,如果不是切入点的增强器,也不是IntroductionAdvisor这种类型的。
48         else {
49              // 将增强器advisor包装一下
50             Interceptor[] interceptors = registry.getInterceptors(advisor);
51             // 将包装的interceptors放到interceptorList集合中
52             interceptorList.addAll(Arrays.asList(interceptors));
53         }
54     }
55 
56     return interceptorList;
57 }

如下所示:

由于遍历增强器都会调用MethodInterceptor[] interceptors = registry.getInterceptors(advisor);方法。

advisor = org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR
interceptors = [org.springframework.aop.interceptor.ExposeInvocationInterceptor@3e6104fc]

点击Step Info(F5)进去。判断,增强器是否是MethodInterceptor类型的,否则,转换为MethodInterceptor类型的,添加到List<MethodInterceptor>集合中。

 1 @Override
 2 public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
 3     // 创建一个interceptors集合。长度定义为3
 4     List<MethodInterceptor> interceptors = new ArrayList<MethodInterceptor>(3);
 5     // 获取到这个增强器
 6     Advice advice = advisor.getAdvice();
 7     // 判断,增强器是否是MethodInterceptor类型的,如果是添加到List<MethodInterceptor>集合中。
 8     if (advice instanceof MethodInterceptor) {
 9         interceptors.add((MethodInterceptor) advice);
10     }
11     // 否则,不是这种类型的。遍历这些,将使用AdvisorAdapter适配器,将这些advice增强器转换为MethodInterceptor类型的,如果是添加到List<MethodInterceptor>集合中。
12     // this.adapters的值如下所示:
13     // org.springframework.aop.framework.adapter.MethodBeforeAdviceAdapter@12359a82
14     // org.springframework.aop.framework.adapter.AfterReturningAdviceAdapter@68df9280
15     // org.springframework.aop.framework.adapter.ThrowsAdviceAdapter@479460a6
16     for (AdvisorAdapter adapter : this.adapters) {
17         if (adapter.supportsAdvice(advice)) {
18             interceptors.add(adapter.getInterceptor(advisor));
19         }
20     }
21     // 如果是空,抛出异常
22     if (interceptors.isEmpty()) {
23         throw new UnknownAdviceTypeException(advisor.getAdvice());
24     }
25     // 将集合转换为数组返回,转换以后返回MethodInterceptor数组
26     return interceptors.toArray(new MethodInterceptor[interceptors.size()]);
27 }

如下所示:

将执行的结果返回,其实就是将增强器包装成为了连接器的过程,直到返回走到List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);拦截器链,即每一个通知方法又被包装成为了方法拦截器,方法的执行都是利用MethodInterceptor方法拦截器机制。

8、AOP原理,链式调用通知方法。retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();这里面的new CglibMethodInvocation(),创建成功以后执行proceed()方法。

创建成功的CglibMethodInvocation会将整个连接器链传过来,传过来以后执行proceed()方法,触发拦截器链的调用过程。

执行拦截器链的操作如下所示。

点击Step Info(F5)进去,点击Step Return(F7)出去,再次点击Step Info(F5)进去。

点击Step Over(F6)进去走到,return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

此时interceptorOrInterceptionAdvice=org.springframework.aop.interceptor.ExposeInvocationInterceptor@3e6104fc。

this=CglibMethodInvocation。

点击Step Info(F5)进去。 每次执行proceed();索引自增一次。

 1 // ThreadLocal是同一条线程共享数据的。即将MethodInvocation进行共享
 2 private static final ThreadLocal<MethodInvocation> invocation =
 3             new NamedThreadLocal<MethodInvocation>("Current AOP method invocation");
 4 
 5 // 
 6 @Override
 7 public Object invoke(MethodInvocation mi) throws Throwable {
 8     // 从ThreadLocal获取到MethodInvocation
 9     MethodInvocation oldInvocation = invocation.get();
10     // 将MethodInvocation设置到ThreadLocal<MethodInvocation>中
11     invocation.set(mi);
12     try {
13         // 执行CglibMethodInvocation的proceed()方法。即((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this)就是执行了MethodInvocation.proceed();
14         // 每次执行proceed();索引自增一次。
15         return mi.proceed();
16     }
17     finally {
18         // 将MethodInvocation设置到ThreadLocal<MethodInvocation>中。
19         invocation.set(oldInvocation);
20     }
21 }

如下图所示:

Step Over(F6)走到return mi.proceed();

点击Step Info(F5)进去。有木有很熟悉,只是这次this.currentInterceptorIndex索引的值已经自增1了。

此时interceptorOrInterceptionAdvice=org.springframework.aop.aspectj.AspectJAfterThrowingAdvice: advice method [public void com.bie.aop.LogAspect.logException(org.aspectj.lang.JoinPoint,java.lang.Exception)]; aspect name 'logAspect'。

this=CglibMethodInvocation。

点击Step Info(F5)进去。

点击Step Info(F5)进去。有木有很熟悉,只是这次this.currentInterceptorIndex索引的值已经自增1了。

此时interceptorOrInterceptionAdvice=org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor@7164ca4c。

this=CglibMethodInvocation。

点击Step Info(F5)进去。 

点击Step Info(F5)进去。 Object retVal = mi.proceed();

此时interceptorOrInterceptionAdvice=org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.bie.aop.LogAspect.logEnd(org.aspectj.lang.JoinPoint)]; aspect name 'logAspect'。

this=CglibMethodInvocation。

点击Step Info(F5)进去。return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); 

点击Step Info(F5)进去。return mi.proceed();

此时interceptorOrInterceptionAdvice=org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@4f3bbf68。

this=CglibMethodInvocation。

点击Step Info(F5)进去。return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);

在调用return mi.proceed();首先执行了前置通知方法,执行效果,如下所示:

点击Step Info(F5)进去。return mi.proceed();

点击Step Over(F6)下一步,运行到return invokeJoinpoint();直接利用反射执行目标方法。前置通知调用结束开始调用目标方法。

前置通知调用结束开始调用目标方法。目标方法执行结束以后,执行后置通知方法。后置通知方法执行以后,如果有异常执行异常通知,如果没有异常执行返回通知。此乃AOP的执行逻辑。

链式获取每一个拦截器,拦截器执行invoke方法,每一个拦截器等待下一个拦截器执行完成返回以后再来执行。拦截器链的机制来保证通知方法和目标方法的执行顺序。

9、AOP原理总结。

 1 第一步、@EnableAspectJAutoProxy开启AOP功能。
 2 第二步、@EnableAspectJAutoProxy注解会给容器中注册一个组件AnnotationAwareAspectJAutoProxyCreator。
 3 第三步、AnnotationAwareAspectJAutoProxyCreator是一个后置处理器。
 4 第四步、容器的创建流程。
 5         1)、registerBeanPostProcessors(beanFactory);注册后置处理器,创建AnnotationAwareAspectJAutoProxyCreator对象。
 6         2)、finishBeanFactoryInitialization(beanFactory);初始化剩余的单实例bean对象。
 7             a)、此时创建业务逻辑组件和切面组件,比如此时的业务逻辑组件MathCalculator、切面组件LogAspect。
 8             b)、AnnotationAwareAspectJAutoProxyCreator拦截组件的创建过程。
 9             c)、组件创建完成以后,判断组件是否包装,需要增强。如果需要进行增强,将切面里面的通知方法包装成增强器(Advisor)。给业务逻辑组件创建一个代理对象,如果有接口创建jdk动态代理,默认创建cglib动态代理。代理对象里面包含所有的增强器。
10 第五步、执行目标方法,即代理对象执行目标方法。
11         1)、CglibAopProxy.intercept()方法,拦截目标方法的执行。
12             a)、获取到目标方法的拦截器链,所谓的拦截器链即增强器,只不过是将增强器包装成为了拦截器链MethodInterceptor。
13             b)、利用拦截器链式机制,依次进入每一个拦截器进行执行。
14             c)、执行效果如下所示:
15                 正常执行流程:前置通知 ---> 目标方法  ---> 后置通知 ---> 返回通知
16                 异常执行流程:前置通知 ---> 目标方法  ---> 后置通知 ---> 异常通知

作者:别先生

博客园:https://www.cnblogs.com/biehongli/

如果您想及时得到个人撰写文章以及著作的消息推送,可以扫描上方二维码,关注个人公众号哦。

 
 

猜你喜欢

转载自www.cnblogs.com/biehongli/p/12034956.html
今日推荐