0%

AOP开启注解

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.handlersMETA-INF/spring.schemas 关联自定义标签与解析逻辑:

  • spring.handlers:映射 “命名空间(namespace)” 到 “标签处理器(NamespaceHandler)”,告诉 Spring 用哪个类解析该命名空间下的标签;
  • spring.schemas:映射 “XSD Schema 地址” 到 “本地 XSD 文件”,用于校验自定义标签的语法合法性。
示例:AOP 自定义标签的配置
1
2
3
4
5
# spring.handlers:aop 命名空间对应 AopNamespaceHandler
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

# spring.schemas:aop XSD 地址对应本地文件(避免联网下载)
http\://www.springframework.org/schema/aop/spring-aop-3.1.xsd=org/springframework/aop/config/spring-aop-3.1.xsd

自定义标签的解析流程

当 Spring 解析 XML 配置遇到自定义标签(如 <aop:aspectj-autoproxy/>)时,执行以下步骤:

  1. 提取命名空间:从标签的 xmlns:aop 属性获取命名空间(http://www.springframework.org/schema/aop);
  2. 获取处理器:通过 NamespaceHandlerResolverspring.handlers 中找到对应的 AopNamespaceHandler
  3. 初始化处理器:调用 AopNamespaceHandler.init() 注册标签解析器;
  4. 解析标签:根据标签名称(aspectj-autoproxy)调用对应的解析器(AspectJAutoProxyBeanDefinitionParser)。

源码印证:

1
2
3
4
5
6
// 1. 提取命名空间,获取对应的 NamespaceHandler
String namespaceUri = getNamespaceURI(ele);
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);

// 2. 调用处理器解析标签(<aop:aspectj-autoproxy/> 对应 AspectJAutoProxyBeanDefinitionParser)
handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));

步骤 1:AopNamespaceHandler 初始化与解析器注册

AopNamespaceHandler 是 AOP 自定义标签的总处理器,其 init() 方法会注册不同标签对应的解析器,核心是为 <aop:aspectj-autoproxy/> 绑定 AspectJAutoProxyBeanDefinitionParser

1. AopNamespaceHandler#init () 源码解析

1
2
3
4
5
6
7
8
9
10
public void init() {
// 1. 解析 <aop:config/> 标签(XML 方式配置 AOP)
registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
// 2. 解析 <aop:aspectj-autoproxy/> 标签(注解方式开启 AOP)
registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
// 3. 解析 <aop:scoped-proxy/> 标签(作用域代理)
registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
// 4. 解析 <aop:spring-configured/> 标签(已过时,移至 context 命名空间)
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
}
  • 关键逻辑registerBeanDefinitionParser("aspectj-autoproxy", ...)<aop:aspectj-autoproxy/> 标签绑定了解析器 AspectJAutoProxyBeanDefinitionParser,后续该标签的解析由这个类完成。

步骤 2:AspectJAutoProxyBeanDefinitionParser 解析标签 —— 注册核心处理器

AspectJAutoProxyBeanDefinitionParser 的核心作用是:解析 <aop:aspectj-autoproxy/> 标签,并向 IOC 容器注册 AnnotationAwareAspectJAutoProxyCreator(AOP 注解功能的核心处理器)。

1. 核心解析逻辑:registerAspectJAnnotationAutoProxyCreatorIfNecessary

1
2
3
4
5
6
7
8
9
10
11
12
class AspectJAutoProxyBeanDefinitionParser implements BeanDefinitionParser {
@Override
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 1. 核心:注册 AnnotationAwareAspectJAutoProxyCreator(若未注册)
AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(parserContext, element);

// 2. 处理标签子节点(如 <aop:include>,指定需要代理的切面)
extendBeanDefinition(element, parserContext);

return null;
}
}
关键方法:AopNamespaceUtils#registerAspectJAnnotationAutoProxyCreatorIfNecessary

该方法的作用是 “确保容器中存在 AnnotationAwareAspectJAutoProxyCreator 的 BeanDefinition”,若已存在则不重复注册,同时处理标签的属性(如 proxy-target-class):

1
2
3
4
5
6
7
8
9
10
11
12
public static void registerAspectJAnnotationAutoProxyCreatorIfNecessary(
ParserContext parserContext, Element element) {
// 1. 注册 AnnotationAwareAspectJAutoProxyCreator,BeanName 为 internalAutoProxyCreator
BeanDefinition beanDefinition = AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(
parserContext.getRegistry(), parserContext.extractSource(element));

// 2. 处理 <aop:aspectj-autoproxy proxy-target-class="true"/> 属性:是否强制 CGLIB 代理
useClassProxyingIfNecessary(parserContext.getRegistry(), element);

// 3. 注册组件(供 Spring 内部跟踪)
registerComponentIfNecessary(beanDefinition, parserContext);
}
  • 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
2
3
4
5
6
7
8
9
// doCreateBean() 中触发 Bean 初始化
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); // 步骤1:属性注入
if (exposedObject != null) {
// 步骤2:初始化 Bean(包含 BeanPostProcessor 调用)
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
}
initializeBean ():BeanPostProcessor 的调用入口
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
protected Object initializeBean(String beanName, Object bean, RootBeanDefinition mbd) {
// 1. Aware 接口回调(如 BeanFactoryAware.setBeanFactory())
invokeAwareMethods(beanName, bean);

// 2. 调用 BeanPostProcessor.postProcessBeforeInitialization()(初始化前)
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

// 3. 执行初始化方法(如 @PostConstruct、init-method)
try {
invokeInitMethods(beanName, wrappedBean, mbd);
} catch (Throwable ex) {
throw new BeanCreationException("初始化方法执行失败", ex);
}

// 4. 调用 BeanPostProcessor.postProcessAfterInitialization()(初始化后)
if (mbd == null || !mbd.isSynthetic()) {
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}

return wrappedBean;
}
  • 关键结论AnnotationAwareAspectJAutoProxyCreatorpostProcessAfterInitialization() 方法在 Bean 初始化完成后调用,此时 Bean 已实例化且属性注入完成,是生成 AOP 代理的最佳时机。

2. 核心方法:postProcessAfterInitialization () 与 wrapIfNecessary ()

AnnotationAwareAspectJAutoProxyCreator 继承自 AbstractAutoProxyCreator,其 postProcessAfterInitialization() 方法最终调用 wrapIfNecessary(),该方法是判断是否生成代理、如何生成代理的核心。

wrapIfNecessary () 源码解析
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
// 1. 跳过已处理的 Bean(如 TargetSource 自定义目标源的 Bean)
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}

// 2. 跳过无需代理的 Bean(已标记为不代理的 Bean)
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}

// 3. 跳过 Spring 内部基础设施 Bean(如 @Aspect 切面类、Advisor 等)
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}

// 4. 核心:查找当前 Bean 匹配的增强器(Advisor)
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
// 标记该 Bean 需要代理
this.advisedBeans.put(cacheKey, Boolean.TRUE);

// 5. 生成 AOP 代理对象
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

// 缓存代理类型
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}

// 标记该 Bean 无需代理
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
关键步骤拆解
(1)isInfrastructureClass ():跳过内部基础设施 Bean
1
2
3
4
5
6
7
8
protected boolean isInfrastructureClass(Class<?> beanClass) {
// 排除 Spring 内部 Bean:Advice、Pointcut、Advisor、AopInfrastructureBean 或 @Aspect 标注的类
return (Advice.class.isAssignableFrom(beanClass) ||
Pointcut.class.isAssignableFrom(beanClass) ||
Advisor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}
  • 原因@Aspect 切面类本身是 “增强器的定义者”,而非 “被代理的目标”,因此无需为其生成代理。
(2)getAdvicesAndAdvisorsForBean ():查找匹配的增强器

该方法的核心是 “从容器中找到所有能应用到当前 Bean 的增强器(Advisor)”,分为两步:

  1. 查找所有候选增强器:扫描容器中 @Aspect 切面类的增强方法(如 @Before 标注的方法),封装为 Advisor
  2. 筛选匹配的增强器:根据切入点(Pointcut)判断增强器是否适用于当前 Bean 的方法。

源码印证:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
// 1. 查找所有能应用到当前 Bean 的增强器
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
if (advisors.isEmpty()) {
return DO_NOT_PROXY; // 无匹配增强器,不代理
}
return advisors.toArray();
}

// 查找 eligible(符合条件)的增强器
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
// 1. 查找所有候选增强器(包括 XML 配置和 @Aspect 注解的增强)
List<Advisor> candidateAdvisors = findCandidateAdvisors();
// 2. 筛选出能匹配当前 Bean 的增强器
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
// 3. 扩展增强器(如添加默认的异常处理增强)
extendAdvisors(eligibleAdvisors);
// 4. 排序增强器(确定执行顺序,如 @Before 先于 @After)
if (!eligibleAdvisors.isEmpty()) {
eligibleAdvisors = sortAdvisors(eligibleAdvisors);
}
return eligibleAdvisors;
}
  • findCandidateAdvisors()AnnotationAwareAspectJAutoProxyCreator 重写了该方法,会额外扫描 @Aspect 切面类的增强方法(通过 aspectJAdvisorsBuilder.buildAspectJAdvisors())。
(3)createProxy ():生成 AOP 代理

当找到匹配的增强器后,createProxy() 会通过 ProxyFactory 生成代理对象,代理类型(JDK/CGLIB)由 proxy-target-class 属性和目标类类型决定:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
protected Object createProxy(
Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {
// 1. 配置 ProxyFactory(AOP 代理的工厂类)
ProxyFactory proxyFactory = new ProxyFactory();
proxyFactory.copyFrom(this); // 继承父类配置(如 proxy-target-class)

// 2. 决定代理类型:JDK 动态代理或 CGLIB 代理
if (!proxyFactory.isProxyTargetClass()) {
// 2.1 若配置了 proxy-target-class="true",强制 CGLIB 代理
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
} else {
// 2.2 否则,若目标类实现接口,使用 JDK 代理;无接口,使用 CGLIB 代理
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}

// 3. 添加增强器(Advisor)到代理工厂
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);

// 4. 设置目标对象(被代理的原始 Bean)
proxyFactory.setTargetSource(targetSource);

// 5. 定制代理(如冻结代理配置,避免后续修改)
customizeProxyFactory(proxyFactory);

// 6. 生成并返回代理对象
return proxyFactory.getProxy(getProxyClassLoader());
}
  • 代理类型决策逻辑:与 ProxyFactoryBean 一致(参考之前的 ProxyFactoryBean 解析),优先根据 proxy-target-class 配置,其次根据目标类是否实现接口。

特殊场景:循环依赖与 AOP 代理的协同

当存在循环依赖(如 A Setter 依赖 B,B Setter 依赖 A)且 Bean 需要 AOP 代理时,Spring 会通过 三级缓存 提前生成代理对象,确保依赖注入的是代理对象(而非原始对象)。

关键方法:getEarlyBeanReference ()

doCreateBean() 中,当 Bean 实例化后、属性注入前,若允许循环依赖,会调用 addSingletonFactory()getEarlyBeanReference() 封装为 ObjectFactory 放入三级缓存:

1
2
3
4
5
6
7
addSingletonFactory(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
// 核心:提前生成代理对象(若需要)
return getEarlyBeanReference(beanName, mbd, bean);
}
});

getEarlyBeanReference()AbstractAutoProxyCreator 实现,会调用 wrapIfNecessary() 提前生成代理:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
protected Object getEarlyBeanReference(String beanName, RootBeanDefinition mbd, Object bean) {
Object exposedObject = bean;
if (bean != null && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
SmartInstantiationAwareBeanPostProcessor ibp = (SmartInstantiationAwareBeanPostProcessor) bp;
// 调用 AbstractAutoProxyCreator 的 getEarlyBeanReference(),内部调用 wrapIfNecessary()
exposedObject = ibp.getEarlyBeanReference(exposedObject, beanName);
if (exposedObject == null) {
return null;
}
}
}
}
return exposedObject;
}
  • 核心作用:在循环依赖场景下,提前为 Bean 生成代理对象,确保依赖方注入的是代理对象,与最终放入一级缓存的代理对象一致。

总结:AOP 注解开启的完整链路

<aop:aspectj-autoproxy/> 配置到 AOP 代理生成,整个流程可精简为 6 步:

  1. XML 解析触发:Spring 解析 XML 时遇到 <aop:aspectj-autoproxy/> 自定义标签;
  2. 自定义标签映射:通过 spring.handlers 找到 AopNamespaceHandler
  3. 解析器注册AopNamespaceHandler.init() 注册 AspectJAutoProxyBeanDefinitionParser
  4. 核心处理器注册AspectJAutoProxyBeanDefinitionParser 向容器注册 AnnotationAwareAspectJAutoProxyCreator
  5. BeanPostProcessor 介入AnnotationAwareAspectJAutoProxyCreatorpostProcessAfterInitialization() 中调用 wrapIfNecessary()
  6. 代理生成wrapIfNecessary() 查找匹配的增强器,通过 ProxyFactory 生成 JDK/CGLIB 代理

欢迎关注我的其它发布渠道

表情 | 预览
快来做第一个评论的人吧~
Powered By Valine
v1.3.10