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