Spring注解驱动开发学习总结12:AOP原理 - @EnableAspectJAutoProxy注解作用分析
在上一篇博文Spring注解驱动开发学习总结11:AOP功能使用,我们学习了AOP的基本使用,下面开始来理解下AOP功能能实现的原理。注:本文用的spring-context是4.3.12.RELEASE版本的。
1、@EnableAspectJAutoProxy注解的作用
首先要能使用AOP,需要在配置类上添加@EnableAspectJAutoProxy注解,因此首先需要来看下@EnableAspectJAutoProxy注解干了点什么事?
1.1 导入AspectJAutoProxyRegistrar类
首先查看@EnableAspectJAutoProxy注解,可以看到112行,该类上面添加了一个@Import注解,该注解导入了一个AspectJAutoProxyRegistrar类。
因此接下来需要看下,AspectJAutoProxyRegistrar这个类干了点什么事?
1.2 容器中注册AnnotationAwareAspectJAutoProxyCreator类
查看AspectJAutoProxyRegistrar类,可以看到它实现了ImportBeanDefinitionRegistrar类的registerBeanDefinitions方法,因此我们可以猜测到,它应该是要给容器中主动注册一个beanDefinition。
接着断点进入45行的registerAspectJAnnotationAutoProxyCreatorIfNecessary方法,通过方法栈可以看到,最后会进入到AopConfigUtils类的109行的registerOrEscalateApcAsRequired方法。
查看AopConfigUtils类的109行的registerOrEscalateApcAsRequired方法。
1)首先在118行,判断是否存在id为internalAutoProxyCreator的组件。由于容器刚创建,条件为false。其中:
AUTO_PROXY_CREATOR_BEAN_NAME = “org.springframework.aop.config.internalAutoProxyCreator”;
2)接下面在125行,给容器注册一个id为internalAutoProxyCreator,类型为org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator的组件。
因此可以看到,实际上就是给容器中注册了一个id为internalAutoProxyCreator,类型为.AnnotationAwareAspectJAutoProxyCreator的组件。
1.3 小结
1、在配置类上必须加@EnableAspectJAutoProxy注解,而@@EnableAspectJAutoProxy注解类上加了@Import(AspectJAutoProxyRegistrar.class),也就是导入了一个AspectJAutoProxyRegistrar类。
2、AspectJAutoProxyRegistrar类中的registerBeanDefinitions方法,最终给容器中注册了一个id为internalAutoProxyCreator,类型为.AnnotationAwareAspectJAutoProxyCreator的组件。
2、AnnotationAwareAspectJAutoProxyCreator类的使用分析
由上一小结可以看到,配置类上加了@EnableAspectJAutoProxy注解,最终会给ioc容器注册一个类型为.AnnotationAwareAspectJAutoProxyCreator的组件。那么接下来就先分析下,注册这个组件大概有什么用?
2.1 继承关系分析
1、AnnotationAwareAspectJAutoProxyCreator类继承自AspectJAwareAdvisorAutoProxyCreator类。
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {}
2、AspectJAwareAdvisorAutoProxyCreator类继承自AbstractAdvisorAutoProxyCreator类。
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {}
3、AbstractAdvisorAutoProxyCreator类继承自AbstractAutoProxyCreator类。
public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {}
4、AbstractAutoProxyCreator类实现了SmartInstantiationAwareBeanPostProcessor类、BeanFactoryAware类
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {}
分析:
1)最终实现了SmartInstantiationAwareBeanPostProcessor接口,因此一定会调用某些postProcessorXxx方法,也就是后置处理方法。这个等会需要再分析下,spring容器使用aop功能,在运行时会调用哪些后置处理方法?
2)还实现了BeanFactoryAware接口,那么一定实现了该接口唯一的setBeanFactory方法。
public interface BeanFactoryAware extends Aware {
void setBeanFactory(BeanFactory beanFactory) throws BeansException;
}
2.2 aop关键方法分析
上面已经分析了AnnotationAwareAspectJAutoProxyCreator类的继承关系,接下来重点看下,它在运行时会调用哪些后置处理方法,以及setBeanFactory方法是如何工作的?
1、查看AbstractAutoProxyCreator类:
可以看到其实现了
1)setBeanFactory方法、2)postProcessBeforeInstantiation方法,即实例化前的后置处理方法、3)postProcessAfterInitialization方法,即初始化后的后置处理方法。
比如AbstractAutoProxyCreator类的postProcessBeforeInstantiation方法的截图如下:
因此,目前的继承关系,以及可能会用到的方法如下:
继承关系 | 后置处理方法 | setBeanFactory方法 |
---|---|---|
AnnotationAwareAspectJAutoProxyCreator | ||
AspectJAwareAdvisorAutoProxyCreator | ||
AbstractAdvisorAutoProxyCreator | ||
AbstractAutoProxyCreator | 1、postProcessBeforeInstantiation; 2、postProcessAfterInitialization | 1、setBeanFactory |
2、查看AbstractAdvisorAutoProxyCreator类:
1)该类在54行重写了setBeanFactory方法,,同时在方法中的第60行,调用了initBeanFactory方法
因此,目前的继承关系,以及可能会用到的方法如下:
继承关系 | 后置处理方法 | setBeanFactory方法 |
---|---|---|
AnnotationAwareAspectJAutoProxyCreator | ||
AspectJAwareAdvisorAutoProxyCreator | ||
AbstractAdvisorAutoProxyCreator | 无重写 | 1、setBeanFactory -> initBeanFactory |
AbstractAutoProxyCreator | 1、postProcessBeforeInstantiation; 2、postProcessAfterInitialization | 1、setBeanFactory |
3、查看AspectJAwareAdvisorAutoProxyCreator类:
在该类中没有看到重写了后置处理方法,以及setBeanFactory方法。
3、查看 AnnotationAwareAspectJAutoProxyCreator 类:
1)该类在75行重写了initBeanFactory方法
因此,目前的继承关系,以及可能会用到的方法如下:
继承关系 | 后置处理方法 | setBeanFactory方法 |
---|---|---|
AnnotationAwareAspectJAutoProxyCreator | 无重写 | 1、initBeanFactory |
AspectJAwareAdvisorAutoProxyCreator | 无重写 | 无重写 |
AbstractAdvisorAutoProxyCreator | 无重写 | 1、setBeanFactory -> initBeanFactory |
AbstractAutoProxyCreator | 1、postProcessBeforeInstantiation; 2、postProcessAfterInitialization | 1、setBeanFactory |
2.3 测试理论分析
上面通过理论,分析出了该类在spring使用aop功能时,可能会运行的后置处理方法、以及setBeanFactory方法。
因此我们可以在以下这些类的方法上打上断点,这样调试aop功能的时候就可以看下,是不是调用了这些方法。
从下图可以看到,spring在使用aop容器时,的确都调用了对应类的方法。
1)AnnotationAwareAspectJAutoProxyCreator类的initBeanFactory方法
2)AbstractAdvisorAutoProxyCreator的setBeanFactory方法:
3)AbstractAutoProxyCreator类的postProcessBeforeInstantiation方法
2.4 小结
在给ioc容器注册一个类型为AnnotationAwareAspectJAutoProxyCreator的组件后,分析出该类的继父类中会运行后置处理方法、以及setBeanFactory方法。因此我们可以对这些方法打上调试的断点,方便之后进行aop的源码调用分析。
继承关系 | 后置处理方法 | setBeanFactory方法 |
---|---|---|
AnnotationAwareAspectJAutoProxyCreator | 无重写 | 1、initBeanFactory |
AspectJAwareAdvisorAutoProxyCreator | 无重写 | 无重写 |
AbstractAdvisorAutoProxyCreator | 无重写 | 1、setBeanFactory -> initBeanFactory |
AbstractAutoProxyCreator | 1、postProcessBeforeInstantiation; 2、postProcessAfterInitialization | 1、setBeanFactory |
3、小结
1、使用AOP功能,要在配置类上加@EnableAspectJAutoProxy注解,而@@EnableAspectJAutoProxy注解类上加了@Import(AspectJAutoProxyRegistrar.class),也就是导入了一个AspectJAutoProxyRegistrar类。
2、AspectJAutoProxyRegistrar类中的registerBeanDefinitions方法,最终给容器中注册了一个id为internalAutoProxyCreator,类型为AnnotationAwareAspectJAutoProxyCreator的组件。
3、注册了类型为AnnotationAwareAspectJAutoProxyCreator的组件,我们理论上分析了该类的父类和所实现的接口,分析出该类在spring使用aop功能时,可能会运行的后置处理方法、以及setBeanFactory方法,并且也通过测试进行了验证。
继承关系 | 后置处理方法 | setBeanFactory方法 |
---|---|---|
AnnotationAwareAspectJAutoProxyCreator | 无重写 | 1、initBeanFactory |
AspectJAwareAdvisorAutoProxyCreator | 无重写 | 无重写 |
AbstractAdvisorAutoProxyCreator | 无重写 | 1、setBeanFactory -> initBeanFactory |
AbstractAutoProxyCreator | 1、postProcessBeforeInstantiation; 2、postProcessAfterInitialization | 1、setBeanFactory |