Spring注解学习_AOP原理1_@EnableAspectJAutoProxy

@EnableAspectJAutoProxy注解是如何起作用的?

” 我们该如何阅读 Spring中 @EnableXXX 的源码?我们应当:

  1. 看这个注解有没有给容器中注册组件
  2. 如果注册组件了,这些组件:什么时候工作?功能是什么?
  3. 搞清楚这些功能后,这个注解的原理也就明白了。“

一时半会看不懂源码原因有很多,我觉得方法名太多太长容易给绕晕了算一个。尝试自己翻译一下,给它起个中文的方法名,会更好理解这个方法的意图。

  1. @EnableAspectJAutoProxy注解类上标有@Import( AspectJAutoProxyRegistrar.class ) 注解,给容器导入了一个AspectJAutoProxyRegistrar组件。

  2. AspectJAutoProxyRegistrar组件实现了ImportBeanDefinitionRegistrar接口:通过实现 registerBeanDefinitions方法,给容器中注册其定义的bean:

    给容器注册 AnnotationAwareAspectJAutoProxyCreator —— “ 注解感知的切面自动代理创建器

  3. 这个AnnotationAwareAspectJAutoProxyCreator在AOP中发挥了关键的作用。

  4. 若要研究,不妨先捋清AnnotationAwareAspectJAutoProxyCreator的继承关系:

    AnnotationAwareAspectJAutoProxyCreator

    ​ ➡️ AspectJAwareAdvisorAutoProxyCreator

    ​ ➡️ AbstractAdvisorAutoProxyCreator

    ​ ➡️ AbstractAutoProxyCreator

    ​ implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
    ​ 关注后置处理器(bean初始化前后做了什么)及BeanFactoryAware

    ​ ➡️ ProxyProcessorSupport

  5. 总结:

    @EnableAspectJAutoProxy注解类上标有@Import( AspectJAutoProxyRegistrar.class ) 注解,给容器导入了一个AspectJAutoProxyRegistrar组件。而这个组件通过实现了mportBeanDefinitionRegistrar接口,给容器中注册了AnnotationAwareAspectJAutoProxyCreator “注解感知的切面自动代理创建者”。

    Spring切面及切面方法的生效,正是靠AnnotationAwareAspectJAutoProxyCreator 这个后置处理器来完成的!

源码走读:

@EnableAspectJAutoProxy

我们直接看到@EnableAspectJAutoProxy这个注解类:

image-20200405032939942

可知:打上@EnableAspectJAutoProxy注解后会同时给容器中导入AspectJAutoProxyRegistrar组件。

AspectJAutoProxyRegistrar组件实现了ImportBeanDefinitionRegistrar接口:通过实现 registerBeanDefinitions方法,给容器中注册其定义的组件 —— 那我们就看看到底注册了什么:

可以看到调用了: AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary( register ) 方法,(中文翻译过来就是:注册 切面注解自动代理创建者 如果需要的话)

image-20200405173844449

这个方法将调用 registerOrEscalateApcAsRequired 方法(中:根据需要注册或升级Apc (自动代理创建者) ),并另外传入AnnotationAwareAspectJAutoProxyCreator 类型作为参数

image-20200405174331612

接下来我们分析 registerOrEscalateApcAsRequired 方法(中:根据需要注册或升级Apc (自动代理创建者) )的逻辑:

(它将用到所在类开头就定义好的静态常量:)

/**
 * The bean name of the internally managed auto-proxy creator.
 */
public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
      "org.springframework.aop.config.internalAutoProxyCreator";

image-20200405190527521

所以这个方法会注册一个AnnotationAwareAspectJAutoProxyCreator(注解感知的 切面 自动代理创建者)

查看这个APC的源码,捋清它的继承树上的一个父类AbstractAutoProxyCreator (抽象 自动代理创建者),这个父类实现了接口:SmartInstantiationAwareBeanPostProcessor(聪明实例化感知 Bean后置处理器), BeanFactoryAware ,即AbstractAutoProxyCreator有两个身份:SmartInstantiationAware后置处理器、自动装配BeanFactory。

我们接下来分析AbstractAutoProxyCreator凭这两个身份到底做了那些事:

SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware何时运行?做了什么?

首先回顾一下我以前对于BeanPostProcessor和XXXAware的学习总结:

BeanPostProcessor:在Bean初始化前后进行一些处理工作

XXXAware:实现这一接口,可注入Spring底层组件

如果:自定义组件 想要使用 Spring容器底层的一些组件(如 ApplicationContext, BeanFactory, xxx)

那么:自定义组件 应当实现:xxxAware 接口 (如 ApplicationContextAware等),在创建对象的时候,会调用接口规定的方法注入相关组件

AbstractAutoProxyCreator抽象类 如何实现这两个接口规定的方法?:

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    ...
    @Override
	public void setBeanFactory(BeanFactory beanFactory) {
		this.beanFactory = beanFactory;
	}
    ...
    @Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
		...
	}
	...
	@Override
	public boolean postProcessAfterInstantiation(Object bean, String beanName) {
		return true;
	}
    ...
}

BeanFactoryAware的实现情况:

  1. AbstractAutoProxyCreator.setBeanFactory(BeanFactory beanFactory) 实现了该接口规定的方法

  2. 该方法被AAPC的子类重写:AbstractAdvisorAutoProxyCreator.setBeanFactory(BeanFactory beanFactory) ,调用父类原有方法的基础上再调用本类的 initBeanFactory 方法image-20200405211839691

  3. AbstractAdvisorAutoProxyCreator的子类的子类,即我们研究的目标类: AnnotationAwareAspectJAutoProxyCreator,对 initBeanFactory 方法进行了重写:

    image-20200406214038055

SmartInstantiationAwareBeanPostProcessor

​ 继承自InstantiationAwareBeanPostProcessor

​ 继承自BeanPostProcessor

注意:BeanPostProcessor是在Bean对象创建后完成初始化前后进行处理的

InstantiationAwareBeanPostProcessor,继承自BeanPostProcessor是在创建Bean实例之前先尝试使用后置处理器返回对象的

故AnnotationAwareAspectJAutoProxyCreator会在创建Bean之前尝试返回Bean实例

AnnotationAwareAspectJAutoProxyCreator会在所有Bean创建之前进行拦截,它实现了InstantiationAwareBeanPostProcessor接口,会调用postProcessBeforeInstantiation方法


所有的问题都集中在 “ AnnotationAwareAspectJAutoProxyCreator是何时被创建的,又是何时起到了何种作用 ” 这个问题上,后续笔记着重记录分析这个问题,并作出总结。源码也不是一天两天就能完全吸收的,那就时不时回来修修补补一番!


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达,邮件至 708801794@qq.com

文章标题:Spring注解学习_AOP原理1_@EnableAspectJAutoProxy

文章字数:1.1k

本文作者:梅罢葛

发布时间:2020-04-05, 03:26:30

最后更新:2020-04-08, 01:20:23

原始链接:https://qiurungeng.github.io/2020/04/05/Spring%E6%B3%A8%E8%A7%A3%E5%AD%A6%E4%B9%A0-AOP%E5%8E%9F%E7%90%861-EnableAspectJAutoProxy/
目录
×

喜欢就点赞,疼爱就打赏