#### **1. Spring Bean 生命周期概述**
Spring Bean 的创建过程主要分为以下几个阶段:
1. **实例化**:通过构造器或工厂方法创建 Bean 的原始对象。
2. **属性填充(DI)**:注入依赖的属性和其他 Bean。
3. **初始化**:
• **BeanPostProcessor 的前置处理**(`postProcessBeforeInitialization`)。
• **自定义初始化方法**(如 `@PostConstruct`、`InitializingBean`)。(依次如 @PostConstruct、InitializingBean的afterPropertiesSet, init-method)
• **BeanPostProcessor 的后置处理**(`postProcessAfterInitialization`)。
#### **2. AOP 代理生成的触发时机**
**AOP 代理的生成发生在 Bean 的初始化阶段之后**,具体由 `BeanPostProcessor` 的 `postProcessAfterInitialization` 方法触发。关键步骤如下:
• **触发点**:当 Spring 容器完成 Bean 的实例化、属性注入和自定义初始化后,会遍历所有 `BeanPostProcessor`,调用其 `postProcessAfterInitialization` 方法。
• **核心类**:`AbstractAutoProxyCreator`(AOP 代理的基类)在此阶段检查 Bean 是否需要被代理。若需要,则动态生成代理对象。
#### **3. 源码解析与流程验证**
**关键源码**(`AbstractAutoProxyCreator#postProcessAfterInitialization`):
```java
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
if (bean != null) {
// 生成缓存键(用于避免重复代理)
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (this.earlyProxyReferences.remove(cacheKey) != bean) {
// 若 Bean 需要代理,则生成代理对象
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
```
• **`wrapIfNecessary` 逻辑**:
• 检查 Bean 是否已存在代理。
• 匹配当前 Bean 是否符合切面规则(如 `@Aspect` 定义的切点)。
• 若匹配,则通过 JDK 动态代理或 CGLIB 生成代理对象。
#### **4. 后置处理器的“惰性”特性**
• **按需触发**:并非所有 Bean 都会触发 AOP 代理生成。**仅当 Bean 匹配到至少一个切面规则时,才会生成代理**,体现“惰性”。
• **缓存机制**:已处理的 Bean 会被缓存(如 `targetSourcedBeans`),避免重复检查与代理生成。
#### **5. 生成代理的具体操作**
• **匹配切面**:通过 `Pointcut` 匹配 Bean 的方法是否需要增强。
• **选择代理方式**:
• **JDK 动态代理**:当 Bean 实现了接口。
• **CGLIB 代理**:当 Bean 未实现接口或强制使用 CGLIB(`proxyTargetClass=true`)。
• **代理对象替换**:容器用代理对象替换原始 Bean,后续操作均基于代理。
#### **6. 示例场景**
**场景**:Bean `UserService` 被 `@Transactional` 标记。
1. **实例化**:创建 `UserService` 原始对象。
2. **属性注入**:填充 `UserRepository` 依赖。
3. **初始化**:
• 执行 `@PostConstruct` 方法。
• `AbstractAutoProxyCreator` 检测到 `UserService` 需事务管理,生成代理对象 `UserService$$EnhancerBySpringCGLIB`。
4. **代理生效**:容器中存储的 `UserService` 实为代理对象,后续调用其方法时,代理会介入执行事务逻辑。
#### **7. 特殊情况处理**
• **循环依赖中的代理**:若存在循环依赖,Spring 会在属性注入阶段提前通过 `ObjectFactory` 生成代理(参考三级缓存机制),但最终仍会在 `postProcessAfterInitialization` 确认代理一致性。
• **AOP 与初始化顺序**:若自定义初始化方法(如 `@PostConstruct`)中调用了代理方法,此时可能因代理未生成而失效。需确保初始化方法不依赖代理增强的逻辑。
---
### **总结**
| **维度** | **说明** |
|-------------------------|-------------------------------------------------------------------------|
| **代理生成时机** | Bean 初始化阶段后,由 `postProcessAfterInitialization` 触发。 |
| **触发操作** | `BeanPostProcessor` 遍历检查,按需生成代理。 |
| **后置处理器惰性** | 是,仅当 Bean 匹配切面规则时才生成代理。 |
| **代理替换机制** | 容器用代理对象替换原始 Bean,后续依赖注入和调用均基于代理。 |
| **循环依赖中的处理** | 通过三级缓存提前暴露代理工厂,确保循环依赖中注入正确的代理对象。 |
**结论**:
Spring AOP 代理对象在 Bean **初始化完成后**由 `AbstractAutoProxyCreator` 动态生成,此过程具有“按需触发”的惰性特征,确保仅增强符合切面规则的 Bean。理解此机制有助于优化 AOP 使用和排查代理相关问题。
- 请尽量让自己的回复能够对别人有帮助
- 支持 Markdown 格式, **粗体**、~~删除线~~、
`单行代码`
- 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
- 图片支持拖拽、截图粘贴等方式上传