前言
相信Spring AOP多数同学都用过,在项目里引入相关依赖包以后在配置类上加上@EnableAspectJAutoProxy的注解就可以完成Spring AOP的初始化基本工作。换句话说这个注解开启了Spring AOP的功能,这篇博客会大家一起探究一下Spring AOP在源码层面的流程,以及项目上加的注解到底做了什么。其中可能会涉及到一些AOP的前提知识,这个可以进入【Spring解读系列目录】找Spring AOP标题里的文章就可以了,当然在介绍过程中遇到可能需要的知识点,如果笔者以前写过,也会把连接贴出来。
@EnableAspectJAutoProxy
既然说到了这个注解,首先看下里面是什么。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
//是否开启CGLIB代理
boolean proxyTargetClass() default false;
//是否把AOP产生的代理暴露出去
boolean exposeProxy() default false;
}
首先是两个变量,默认值为false,作用是什么已经写到注解里了,和本篇内容关系不大不多说,重点就在于@Import(AspectJAutoProxyRegistrar.class)这行代码。在这个注解里引入了一个AspectJAutoProxyRegistrar的类,那么进入这个类。
AspectJAutoProxyRegistrar
熟悉Spring框架的同学看见这个名字就应该很熟悉了,一般情况下都会实现ImportBeanDefinitionRegistrar接口,用来干预Bean的生成。详细【Spring框架中ImportBeanDefinitionRegistrar的应用】。
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
//这俩都是false不会进逻辑
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}
这里面并没有什么重要的地方,只是调用了registerAspectJAnnotationAutoProxyCreatorIfNecessary()方法去处理registry,继续进入。
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
空壳方法,继续。
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
发现里面也是调用了一个方法,并且传递了一个AnnotationAwareAspectJAutoProxyCreator类进去了,点进去registerOrEscalateApcAsRequired()方法,注意上面代码source是null。
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
/**无关代码,略去**/
//转换传递进来的AnnotationAwareAspectJAutoProxyCreator类成为beanDefinition
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
//注册到BeanDefinition的Map中,但是注意此时并不是做了bean的初始化,bean初始化还在后面
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
最终把AnnotationAwareAspectJAutoProxyCreator和AUTO_PROXY_CREATOR_BEAN_NAME对应一起注册进Spring容器中,完成了@EnableAspectJAutoProxy的使命。AUTO_PROXY_CREATOR_BEAN_NAME这个是一个bean name常量。
/**
* The bean name of the internally managed auto-proxy creator.
*/
public static final String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
用来标识自动创建代理的bean的名字,程序运行到这里就和AnnotationAwareAspectJAutoProxyCreator类对应起来了。那么我们的重点又改变了,这个Creator类又是什么呢?

最终发现这个类其实是实现了BeanPostProcessor接口的,也就意味着AnnotationAwareAspectJAutoProxyCreator将会变成Spring启动时候的后置处理器之一,还有其他6个有机会介绍。如果这是一个后置处理器,就将会在Spring启动的时候调用BeanPostProcessor接口方法做一些额外的操作,去完成AOP代理的功能。BeanPostProcessor相关知识参考【Spring后置处理器BeanPostProcessor的应用】。
总结
通过上面源码里的探究,在项目里开启@EnableAspectJAutoProxy注解,将会把一个AnnotationAwareAspectJAutoProxyCreator后置处理器加入到Spring Bean的初始化过程中,在这个过程中进行代理并且完成AOP的功能。限于篇幅我们将会在下一篇【Spring源码解析AOP(二)AOP后置处理器的工作】连带着Spring Bean的初始化的部分知识一起讲解,后续这个处理器做了什么。

4万+





