Spring源码解析AOP(一)@EnableAspectJAutoProxy的使命

前言

相信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;
}

最终把AnnotationAwareAspectJAutoProxyCreatorAUTO_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的初始化的部分知识一起讲解,后续这个处理器做了什么。

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值