Spring AOP 注解开启全流程源码解析:从 <aop:aspectj-autoproxy/> 到代理生成
Spring AOP 注解功能(如 @Aspect、@Before)的开启依赖 <aop:aspectj-autoproxy/> 配置,其底层是一套 “自定义标签解析→核心处理器注册→BeanPostProcessor 介入→AOP 代理生成” 的完整链路。从 “自定义标签解析”“核心处理器初始化”“BeanPostProcessor 调用时机”“AOP 代理生成” 四个维度,逐行拆解 AOP 注解开启的底层逻辑。
前置知识:Spring 自定义标签解析机制
<aop:aspectj-autoproxy/> 并非 Spring 内置的 “默认标签”(如 <bean>、<import>),而是自定义标签。Spring 解析自定义标签需依赖两个核心配置文件和一套解析流程:
自定义标签的核心配置文件
Spring 通过类路径下的 META-INF/spring.handlers 和 META-INF/spring.schemas 关联自定义标签与解析逻辑:
spring.handlers:映射 “命名空间(namespace)” 到 “标签处理器(NamespaceHandler)”,告诉 Spring 用哪个类解析该命名空间下的标签;spring.schemas:映射 “XSD Schema 地址” 到 “本地 XSD 文件”,用于校验自定义标签的语法合法性。
示例:AOP 自定义标签的配置
1 | # spring.handlers:aop 命名空间对应 AopNamespaceHandler |
自定义标签的解析流程
当 Spring 解析 XML 配置遇到自定义标签(如 <aop:aspectj-autoproxy/>)时,执行以下步骤:
- 提取命名空间:从标签的
xmlns:aop属性获取命名空间(http://www.springframework.org/schema/aop); - 获取处理器:通过
NamespaceHandlerResolver从spring.handlers中找到对应的AopNamespaceHandler; - 初始化处理器:调用
AopNamespaceHandler.init()注册标签解析器; - 解析标签:根据标签名称(
aspectj-autoproxy)调用对应的解析器(AspectJAutoProxyBeanDefinitionParser)。
源码印证:
1 | // 1. 提取命名空间,获取对应的 NamespaceHandler |
步骤 1:AopNamespaceHandler 初始化与解析器注册
AopNamespaceHandler 是 AOP 自定义标签的总处理器,其 init() 方法会注册不同标签对应的解析器,核心是为 <aop:aspectj-autoproxy/> 绑定 AspectJAutoProxyBeanDefinitionParser。
1. AopNamespaceHandler#init () 源码解析
1 | public void init() { |
- 关键逻辑:
registerBeanDefinitionParser("aspectj-autoproxy", ...)为<aop:aspectj-autoproxy/>标签绑定了解析器AspectJAutoProxyBeanDefinitionParser,后续该标签的解析由这个类完成。
步骤 2:AspectJAutoProxyBeanDefinitionParser 解析标签 —— 注册核心处理器
AspectJAutoProxyBeanDefinitionParser 的核心作用是:解析 <aop:aspectj-autoproxy/> 标签,并向 IOC 容器注册 AnnotationAwareAspectJAutoProxyCreator(AOP 注解功能的核心处理器)。
1. 核心解析逻辑:registerAspectJAnnotationAutoProxyCreatorIfNecessary
1 | class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser { |
关键方法:AopNamespaceUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary
该方法的作用是 “确保容器中存在 AnnotationAwareAspectJAutoProxyCreator 的 BeanDefinition”,若已存在则不重复注册,同时处理标签的属性(如 proxy-target-class):
1 | public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary( |
proxy-target-class属性:若设为true,Spring 会强制使用 CGLIB 代理(即使目标类实现接口);默认false,优先使用 JDK 动态代理。
2. AnnotationAwareAspectJAutoProxyCreator:AOP 注解的核心处理器
AnnotationAwareAspectJAutoProxyCreator 是 Spring AOP 注解功能的 “大脑”,其类结构决定了它的核心能力:
BeanPostProcessor:允许它在 Bean 实例化、初始化前后介入,核心是postProcessAfterInitialization()方法中生成 AOP 代理;BeanFactoryAware:允许它获取BeanFactory,用于扫描容器中的@Aspect切面类和增强方法(如@Before、@After)。
步骤 3:BeanPostProcessor 的调用时机 ——AOP 代理的介入点
AnnotationAwareAspectJAutoProxyCreator 实现了 BeanPostProcessor 接口,Spring 会在 Bean 初始化阶段 调用其 postProcessBeforeInitialization() 和 postProcessAfterInitialization() 方法,其中 postProcessAfterInitialization() 是生成 AOP 代理的核心时机。
1. BeanPostProcessor 的调用链路
Spring 在 doCreateBean()(Bean 创建的核心方法)中,通过 initializeBean() 调用 BeanPostProcessor:
1 | // doCreateBean() 中触发 Bean 初始化 |
initializeBean ():BeanPostProcessor 的调用入口
1 | protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) { |
- 关键结论:
AnnotationAwareAspectJAutoProxyCreator的postProcessAfterInitialization()方法在 Bean 初始化完成后调用,此时 Bean 已实例化且属性注入完成,是生成 AOP 代理的最佳时机。
2. 核心方法:postProcessAfterInitialization () 与 wrapIfNecessary ()
AnnotationAwareAspectJAutoProxyCreator 继承自 AbstractAutoProxyCreator,其 postProcessAfterInitialization() 方法最终调用 wrapIfNecessary(),该方法是判断是否生成代理、如何生成代理的核心。
wrapIfNecessary () 源码解析
1 | protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) { |
关键步骤拆解
(1)isInfrastructureClass ():跳过内部基础设施 Bean
1 | protected boolean isInfrastructureClass(Class<?> beanClass) { |
- 原因:
@Aspect切面类本身是 “增强器的定义者”,而非 “被代理的目标”,因此无需为其生成代理。
(2)getAdvicesAndAdvisorsForBean ():查找匹配的增强器
该方法的核心是 “从容器中找到所有能应用到当前 Bean 的增强器(Advisor)”,分为两步:
- 查找所有候选增强器:扫描容器中
@Aspect切面类的增强方法(如@Before标注的方法),封装为Advisor; - 筛选匹配的增强器:根据切入点(Pointcut)判断增强器是否适用于当前 Bean 的方法。
源码印证:
1 | protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) { |
findCandidateAdvisors():AnnotationAwareAspectJAutoProxyCreator重写了该方法,会额外扫描@Aspect切面类的增强方法(通过aspectJAdvisorsBuilder.buildAspectJAdvisors())。
(3)createProxy ():生成 AOP 代理
当找到匹配的增强器后,createProxy() 会通过 ProxyFactory 生成代理对象,代理类型(JDK/CGLIB)由 proxy-target-class 属性和目标类类型决定:
1 | protected Object createProxy( |
- 代理类型决策逻辑:与
ProxyFactoryBean一致(参考之前的 ProxyFactoryBean 解析),优先根据proxy-target-class配置,其次根据目标类是否实现接口。
特殊场景:循环依赖与 AOP 代理的协同
当存在循环依赖(如 A Setter 依赖 B,B Setter 依赖 A)且 Bean 需要 AOP 代理时,Spring 会通过 三级缓存 提前生成代理对象,确保依赖注入的是代理对象(而非原始对象)。
关键方法:getEarlyBeanReference ()
在 doCreateBean() 中,当 Bean 实例化后、属性注入前,若允许循环依赖,会调用 addSingletonFactory() 将 getEarlyBeanReference() 封装为 ObjectFactory 放入三级缓存:
1 | addSingletonFactory(beanName, new ObjectFactory<Object>() { |
getEarlyBeanReference() 由 AbstractAutoProxyCreator 实现,会调用 wrapIfNecessary() 提前生成代理:
1 | protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) { |
- 核心作用:在循环依赖场景下,提前为 Bean 生成代理对象,确保依赖方注入的是代理对象,与最终放入一级缓存的代理对象一致。
总结:AOP 注解开启的完整链路
从 <aop:aspectj-autoproxy/> 配置到 AOP 代理生成,整个流程可精简为 6 步:
- XML 解析触发:Spring 解析 XML 时遇到
<aop:aspectj-autoproxy/>自定义标签; - 自定义标签映射:通过
spring.handlers找到AopNamespaceHandler; - 解析器注册:
AopNamespaceHandler.init()注册AspectJAutoProxyBeanDefinitionParser; - 核心处理器注册:
AspectJAutoProxyBeanDefinitionParser向容器注册AnnotationAwareAspectJAutoProxyCreator; - BeanPostProcessor 介入:
AnnotationAwareAspectJAutoProxyCreator在postProcessAfterInitialization()中调用wrapIfNecessary(); - 代理生成:
wrapIfNecessary()查找匹配的增强器,通过ProxyFactory生成 JDK/CGLIB 代理

v1.3.10