引言
Spring框架的核心能力之一是依赖注入(DI) 和生命周期管理 ,而实现这一能力的核心组件是BeanPostProcessor
(Bean后处理器)。它贯穿Bean的整个生命周期,负责处理依赖注入、生命周期回调、属性绑定等关键逻辑。本文将结合源码示例,深入解析Spring Bean后处理器的执行流程,覆盖依赖注入(@Autowired
/@Resource
)、初始化回调(@PostConstruct
/@PreDestroy
)、配置属性绑定(@ConfigurationProperties
)等核心场景,并通过手动模拟验证底层实现原理。
一、Spring容器初始化全流程概览
要理解BeanPostProcessor
的作用,首先需要明确Spring容器的初始化流程。以下是基于GenericApplicationContext
的典型流程(对应refresh()
方法核心逻辑):
- 容器创建 :初始化
BeanFactory
、BeanDefinitionRegistry
等核心组件。 - Bean定义注册 :将用户定义的Bean(如
BeanPostProcessorA
)转换为BeanDefinition
并存入beanDefinitionMap
。 - 后处理器注册 :注册Spring内置的
BeanPostProcessor
(如AutowiredAnnotationBeanPostProcessor
)及自定义后处理器。 - Bean实例化与初始化 :根据
BeanDefinition
创建Bean实例,依次执行依赖注入、初始化回调。 - 容器刷新完成 :触发
ContextRefreshedEvent
,通知监听器。 - 容器关闭 :触发
@PreDestroy
回调,销毁Bean,清空缓存。
本文将通过BeanPostProcessorCase
主类演示这一完整流程,并结合AutowiredPostProcessorCase
手动模拟@Autowired
的处理逻辑。
二、BeanPostProcessorCase深度解析:Spring自动流程
2.1 容器初始化与Bean注册
2.1.1 容器创建
主方法中首先创建GenericApplicationContext
:
java
GenericApplicationContext context = new GenericApplicationContext();
此时容器处于初始状态 :beanDefinitionMap
为空(无Bean定义),singletonObjects
缓存为空(无单例Bean)。
2.1.2 Bean定义注册
通过registerBean
方法注册测试Bean(BeanPostProcessorA
、B
、C
、E
):
java
context.registerBean(BeanPostProcessorA.class);
context.registerBean(BeanPostProcessorB.class);
// ...其他Bean
registerBean
方法内部会:
- 创建
BeanDefinition
(默认使用RootBeanDefinition
)。 - 将
BeanDefinition
存入beanFactory.beanDefinitionMap
(键为Bean名称,默认是类名首字母小写)。 - 若Bean是
FactoryBean
,会额外处理FactoryBean
的元数据。
此时beanDefinitionMap
的大小为4(对应4个注册的Bean),但尚未实例化任何Bean。
2.2 后处理器注册:Spring内置组件的协作
Spring通过BeanPostProcessor
扩展点实现功能解耦,主方法中显式注册了3类核心后处理器:
2.2.1 AutowiredAnnotationBeanPostProcessor:依赖注入处理器
负责处理@Autowired
、@Value
注解的依赖注入,执行顺序最先(在Bean实例化后、初始化前)。
2.2.2 CommonAnnotationBeanPostProcessor:生命周期处理器
负责处理@Resource
(JSR-250)、@PostConstruct
、@PreDestroy
注解,执行顺序在AutowiredAnnotationBeanPostProcessor
之后。
2.2.3 ConfigurationPropertiesBindingPostProcessor:配置属性绑定处理器
负责将配置文件(如application.properties
)中以${prefix}.
开头的属性绑定到@ConfigurationProperties
标记的Bean,由Spring Boot自动注册(此处手动调用register
方法)。
注册顺序的关键性 :
BeanPostProcessor
的执行顺序由注册顺序决定。例如,AutowiredAnnotationBeanPostProcessor
需先于CommonAnnotationBeanPostProcessor
执行,因为@Resource
可能依赖@Autowired
注入的Bean。
2.3 依赖注入:@Autowired/@Resource/@Value的处理
以BeanPostProcessorA
为例,其包含@Autowired
、@Resource
、@Value
三种注入方式,Spring按以下顺序处理:
2.3.1 @Autowired注入(方法注入)
BeanPostProcessorA
的setBeanPostProcessorB
方法被@Autowired
标记:
java
@Autowired
public void setBeanPostProcessorB(BeanPostProcessorB beanPostProcessorB) {
// 注入逻辑
}
Spring处理@Autowired
的流程(对应AutowiredAnnotationBeanPostProcessor.postProcessProperties
方法):
- 扫描元数据 :通过反射扫描所有
@Autowired
标注的方法、字段,生成InjectionMetadata
(记录所有需要注入的元素)。 - 依赖查找 :对于每个注入点(如
BeanPostProcessorB
类型),通过BeanFactory
查找匹配的Bean(按类型匹配,若有多个则按@Qualifier
或名称匹配)。 - 属性注入 :调用目标方法(如
setBeanPostProcessorB
)传入找到的Bean实例。
关键源码逻辑 (AutowiredAnnotationBeanPostProcessor.postProcessProperties
):
java
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
// 1. 获取或生成InjectionMetadata(包含所有@Autowired/@Value元素)
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
// 2. 执行注入
metadata.inject(bean, beanName, pvs);
return pvs;
}
2.3.2 @Resource注入(方法注入)
BeanPostProcessorA
的setBeanPostProcessorC
方法被@Resource
标记:
java
@Resource
public void setBeanPostProcessorC(BeanPostProcessorC beanPostProcessorC) {
// 注入逻辑
}
@Resource
的处理由CommonAnnotationBeanPostProcessor
完成,流程与@Autowired
类似,但支持按名称匹配(若name
属性存在)。
2.3.3 @Value注入(方法参数)
BeanPostProcessorA
的setHome
方法通过@Value("${JAVA_HOME}")
注入环境变量:
java
@Autowired
public void setHome(@Value("${JAVA_HOME}") String home) {
// 注入逻辑
}
@Value
的解析依赖ContextAnnotationAutowireCandidateResolver
(已通过setDefaultListableBeanFactory
配置),它会解析${}
占位符为环境变量值(如System.getenv("JAVA_HOME")
)。
2.4 生命周期回调:@PostConstruct/@PreDestroy
BeanPostProcessorA
的init
(@PostConstruct
)和destroy
(@PreDestroy
)方法由CommonAnnotationBeanPostProcessor
处理:
2.4.1 @PostConstruct(初始化前回调)
执行时机:依赖注入完成后,InitializingBean.afterPropertiesSet()
之前。
源码逻辑(CommonAnnotationBeanPostProcessor.postProcessBeforeInitialization
):
java
public Object postProcessBeforeInitialization(Object bean, String beanName) {
// 查找@PostConstruct方法并执行
return invokeAwareMethods(beanName, bean);
}
2.4.2 @PreDestroy(销毁前回调)
执行时机:容器关闭时,DisposableBean.destroy()
之前。
源码逻辑(CommonAnnotationBeanPostProcessor.postProcessAfterInitialization
):
java
public Object postProcessAfterInitialization(Object bean, String beanName) {
// 记录@PreDestroy方法,待销毁时调用
return bean;
}
2.5 配置属性绑定:@ConfigurationProperties
BeanPostProcessorE
通过@ConfigurationProperties(prefix = "java")
绑定JDK环境变量(如java.home
、java.version
),处理流程如下:
2.5.1 元数据解析
Spring Boot通过ConfigurationPropertiesBindingPostProcessor
扫描@ConfigurationProperties
标记的类,解析其字段与配置文件前缀的映射关系(如home
字段对应java.home
)。
2.5.2 属性绑定
在Bean实例化后,ConfigurationPropertiesBindingPostProcessor
会将配置文件中匹配的属性值注入到Bean的字段中(通过反射设置字段值)。
三、AutowiredPostProcessorCase:手动模拟@Autowired处理流程
为了深入理解@Autowired
的底层逻辑,我们手动模拟Spring的处理流程,重点关注依赖注入元数据生成 和实际注入执行。
3.1 容器与基础Bean注册
首先创建DefaultListableBeanFactory
并注册基础Bean(BeanPostProcessorB
、C
等):
java
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
factory.registerSingleton("beanPostProcessorB", new BeanPostProcessorCase.BeanPostProcessorB());
// ...其他Bean
registerSingleton
直接将Bean实例存入singletonObjects
缓存(跳过实例化和依赖注入阶段),模拟已初始化的成品Bean。
3.2 依赖注入元数据生成(InjectionMetadata)
AutowiredAnnotationBeanPostProcessor
通过findAutowiringMetadata
方法生成InjectionMetadata
,记录所有需要注入的元素(如@Autowired
方法、@Resource
字段)。
3.2.1 反射调用私有方法
由于findAutowiringMetadata
是私有方法,需通过反射调用:
java
Method findAutowiringMetadataMethod = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod(
"findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
findAutowiringMetadataMethod.setAccessible(true);
InjectionMetadata injectionMetadata = (InjectionMetadata) findAutowiringMetadataMethod.invoke(
processor, "beanPostProcessorA", beanA.getClass(), null);
3.2.2 InjectionMetadata结构
InjectionMetadata
包含injectedElements
(所有需要注入的元素),每个元素是InjectedElement
(记录注入目标的位置和依赖描述符)。
3.3 依赖注入执行(InjectionMetadata.inject)
生成InjectionMetadata
后,调用inject
方法执行实际注入:
java
processor.postProcessProperties(null, beanA, "beanPostProcessorA"); // 触发@Autowired注入
metadata.inject(beanH, "beanPostProcessorH", null); // 触发@Resource/@Value注入
3.3.1 按类型依赖解析(@Autowired)
对于@Autowired
注入的BeanPostProcessorB
,Spring通过BeanFactory.getBean(Class<T>)
查找匹配的单例Bean(beanPostProcessorB
已注册,直接返回)。
3.3.2 按名称依赖解析(@Resource)
@Resource
默认按名称匹配(name
属性为beanPostProcessorC
),查找beanFactory
中名称为beanPostProcessorC
的单例Bean。
3.3.3 @Value占位符解析
@Value("${JAVA_HOME}")
通过ContextAnnotationAutowireCandidateResolver
解析为环境变量值(如/usr/lib/jvm/java-17-openjdk
)。
3.4 验证依赖解析逻辑
通过手动解析依赖验证流程:
java
// 解析@Autowired字段beanPostProcessorF(单例Bean)
Field fField = beanH.getClass().getDeclaredField("beanPostProcessorF");
DependencyDescriptor fDescriptor = new DependencyDescriptor(fField, false);
Object fObject = factory.doResolveDependency(fDescriptor, "beanPostProcessorH", null, null);
// 输出:03:53:39.736 [main] INFO com.dwl.post_processor.AutowiredPostProcessorCase -- @Autowired 字段 beanPostProcessorF 解析结果: com.dwl.post_processor.BeanPostProcessorCase$BeanPostProcessorF@9353778
// 解析@Resource方法参数beanPostProcessorG(单例Bean)
Method gMethod = beanH.getClass().getDeclaredMethod("setBeanPostProcessorG", BeanPostProcessorCase.BeanPostProcessorG.class);
MethodParameter gParam = new MethodParameter(gMethod, 0);
DependencyDescriptor gDescriptor = new DependencyDescriptor(gParam, false);
Object gObject = factory.doResolveDependency(gDescriptor, "beanPostProcessorH", null, null);
// 输出:03:53:39.737 [main] INFO com.dwl.post_processor.AutowiredPostProcessorCase -- @Resource 方法参数 beanPostProcessorG 解析结果: com.dwl.post_processor.BeanPostProcessorCase$BeanPostProcessorG@5e82df6a
// 解析@Value注入的JAVA_HOME
Method homeMethod = beanH.getClass().getDeclaredMethod("setHome", String.class);
MethodParameter homeParam = new MethodParameter(homeMethod, 0);
DependencyDescriptor homeDescriptor = new DependencyDescriptor(homeParam, false);
Object homeObject = factory.doResolveDependency(homeDescriptor, "beanPostProcessorH", null, null);
// 输出:03:53:39.737 [main] INFO com.dwl.post_processor.AutowiredPostProcessorCase -- @Value 注入 JAVA_HOME 解析结果: G:\DevelopmentSoftware\JAVA-17
四、总结与扩展
4.1 核心结论
- BeanPostProcessor执行顺序 :
AutowiredAnnotationBeanPostProcessor
→CommonAnnotationBeanPostProcessor
→ConfigurationPropertiesBindingPostProcessor
。 - 依赖注入流程 :元数据生成(
InjectionMetadata
)→ 依赖查找(BeanFactory
)→ 属性注入(方法/字段赋值)。 - 生命周期回调 :
@PostConstruct
(初始化前)→InitializingBean.afterPropertiesSet()
(可选)→ 自定义初始化方法 →@PreDestroy
(销毁前)→DisposableBean.destroy()
(可选)→ 自定义销毁方法。
4.2 扩展思考
- 自定义BeanPostProcessor :可通过实现
BeanPostProcessor
接口,插入自定义逻辑(如AOP织入、属性校验)。 - 循环依赖处理 :Spring通过三级缓存(
singletonFactories
)解决循环依赖,需结合@Autowired
的字段注入场景理解。 - 配置属性绑定优化 :
@ConfigurationProperties
支持类型安全的校验(如@Validated
),可结合Binder
工具类手动绑定配置。
完整代码
java
package com.dwl.post_processor;
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
import jakarta.annotation.Resource;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor;
import org.springframework.context.annotation.CommonAnnotationBeanPostProcessor;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.context.support.GenericApplicationContext;
/**
* @ClassName BeanPostProcessorCase
* @Description 演示 Spring 核心 Bean 后处理器(BeanPostProcessor)的完整执行流程,
* 涵盖依赖注入(@Autowired/@Resource)、初始化回调(@PostConstruct/@PreDestroy)、
* 配置属性绑定(@ConfigurationProperties)的执行逻辑。
* @Version 1.0.0
* @Date 2025
* @Author By Dwl
*/
@Slf4j
public class BeanPostProcessorCase {
/**
* 主方法:驱动整个 Spring 容器的初始化、刷新和销毁流程。
* 对应 Spring 源码中的 {@link GenericApplicationContext#refresh()} 方法入口。
*/
public static void main(String[] args) {
// 1. 创建空容器(未初始化任何 Bean 定义或后处理器)
GenericApplicationContext context = new GenericApplicationContext();
log.info("[main] 1. 创建 GenericApplicationContext,初始状态:beanDefinitionMap={}, singletonObjects={}",
context.getBeanFactory().getBeanDefinitionCount(), context.getBeanFactory().getSingletonCount());
// 2. 注册自定义 Bean 到容器(生成 BeanDefinition 并存入 beanDefinitionMap)
// 对应 Spring 源码中的 {@link GenericApplicationContext#registerBean(Class)} 方法
context.registerBean(BeanPostProcessorA.class); // 包含多种注解的测试 Bean
context.registerBean(BeanPostProcessorB.class); // 被 A 依赖的 Bean
context.registerBean(BeanPostProcessorC.class); // 被 A 依赖的 Bean
context.registerBean("beanPostProcessorE", BeanPostProcessorE.class); // 配置属性绑定测试 Bean
log.info("[main] 2. 注册自定义 Bean 后,beanDefinitionMap 包含 {} 个 BeanDefinition",
context.getBeanFactory().getBeanDefinitionCount());
// 3. 配置容器解析规则:支持 @Value 的 ${} 占位符解析
// 对应 Spring 源码中的 {@link DefaultListableBeanFactory#setAutowireCandidateResolver(AutowireCandidateResolver)}
context.getDefaultListableBeanFactory().setAutowireCandidateResolver(
new ContextAnnotationAutowireCandidateResolver() // 支持 @Value 的解析器
);
log.info("[main] 3. 配置 AutowireCandidateResolver,启用 @Value 占位符解析");
// 4. 注册核心 BeanPostProcessor(按执行顺序排列)
// 对应 Spring 源码中的 {@link AbstractApplicationContext#registerBeanPostProcessors(ConfigurableListableBeanFactory)}
context.registerBean(AutowiredAnnotationBeanPostProcessor.class); // 依赖注入处理器(@Autowired/@Value)
context.registerBean(CommonAnnotationBeanPostProcessor.class); // 生命周期处理器(@Resource/@PostConstruct/@PreDestroy)
// 手动注册 ConfigurationPropertiesBindingPostProcessor(Spring Boot 自动完成)
ConfigurationPropertiesBindingPostProcessor.register(context.getDefaultListableBeanFactory());
log.info("[main] 4. 注册 BeanPostProcessor:AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor、ConfigurationPropertiesBindingPostProcessor");
// 5. 刷新容器(触发 Bean 生命周期全流程:实例化→注入→初始化→销毁)
// 对应 Spring 源码中的 {@link AbstractApplicationContext#refresh()} 核心方法
context.refresh();
log.info("[main] 5. 容器刷新完成,当前单例 Bean 数量:{}", context.getBeanFactory().getSingletonCount());
// 6. 验证 BeanPostProcessorE 的配置绑定结果
log.info("[main] beanPostProcessorE: {}", context.getBean("beanPostProcessorE"));
// 7. 关闭容器(触发 @PreDestroy 回调和资源清理)
// 对应 Spring 源码中的 {@link AbstractApplicationContext#close()} 方法
context.close();
log.info("[main] 7. 容器关闭完成,singletonObjects 缓存已清空");
}
/**
* 测试 Bean:包含 @Autowired、@Resource、@PostConstruct、@PreDestroy、@Value 注解,
* 用于验证 Spring 依赖注入和生命周期回调的执行顺序。
*/
@Slf4j
static class BeanPostProcessorA {
private BeanPostProcessorB beanPostProcessorB; // 被 @Resource 注入
private BeanPostProcessorC beanPostProcessorC; // 被 @Autowired 注入
private String home; // 被 @Value 注入
/**
* @Autowired 注入(方法注入)
* 执行时机:依赖注入阶段(@PostConstruct 之前)
* 对应 Spring 源码中的 {@link AutowiredAnnotationBeanPostProcessor#postProcessProperties(PropertyValues, Object, String)}
*/
@Autowired
public void setBeanPostProcessorB(BeanPostProcessorB beanPostProcessorB) {
log.info("[BeanPostProcessorA] @Autowired 生效,注入 BeanPostProcessorB: {}", beanPostProcessorB);
this.beanPostProcessorB = beanPostProcessorB;
}
/**
* @Resource 注入(方法注入)
* 执行时机:依赖注入阶段(@Autowired 之后,顺序由 @Resource 的 name 属性决定)
* 对应 Spring 源码中的 {@link CommonAnnotationBeanPostProcessor#postProcessProperties(PropertyValues, Object, String)}
*/
@Resource
public void setBeanPostProcessorC(BeanPostProcessorC beanPostProcessorC) {
log.info("[BeanPostProcessorA] @Resource 生效,注入 BeanPostProcessorC: {}", beanPostProcessorC);
this.beanPostProcessorC = beanPostProcessorC;
}
/**
* @Value 注入(方法参数)
* 执行时机:依赖注入阶段(与 @Autowired 同阶段)
* 对应 Spring 源码中的 {@link AutowiredAnnotationBeanPostProcessor#postProcessProperties(PropertyValues, Object, String)}
*/
@Autowired
public void setHome(@Value("${JAVA_HOME}") String home) {
log.info("[BeanPostProcessorA] @Value 生效,注入 JAVA_HOME: {}", home);
this.home = home;
}
/**
* @PostConstruct 初始化回调
* 执行时机:依赖注入完成后,初始化方法(如 InitializingBean.afterPropertiesSet)之前
* 对应 Spring 源码中的 {@link CommonAnnotationBeanPostProcessor#postProcessBeforeInitialization(Object, String)}
*/
@PostConstruct
public void init() {
log.info("[BeanPostProcessorA] @PostConstruct 生效,完成初始化");
}
/**
* @PreDestroy 销毁回调
* 执行时机:容器关闭时,在 Bean 实际销毁前调用
* 对应 Spring 源码中的 {@link CommonAnnotationBeanPostProcessor#postProcessAfterInitialization(Object, String)}
*/
@PreDestroy
public void destroy() {
log.info("[BeanPostProcessorA] @PreDestroy 生效,准备销毁");
}
@Override
public String toString() {
return "BeanPostProcessorA{" +
"beanPostProcessorB=" + beanPostProcessorB +
", beanPostProcessorC=" + beanPostProcessorC +
", home='" + home + '\'' +
'}';
}
}
// 以下为辅助测试 Bean(无特殊注解)
static class BeanPostProcessorB {
}
static class BeanPostProcessorC {
}
static class BeanPostProcessorF {
}
static class BeanPostProcessorG {
}
/**
* 演示 Spring 配置属性绑定(@ConfigurationProperties)的核心流程,
* 用于将配置文件中以 "java." 为前缀的属性(如 java.home、java.version)绑定到 Bean 的字段。
* <p>
* 关键流程解析:
* 1. 类级别注解 {@link ConfigurationProperties()}:声明该 Bean 用于绑定配置属性,
* 其中 prefix="java" 表示只读取配置文件中以 "java." 开头的属性(如 java.home、java.version)。
* 2. 字段映射:类中的字段(home、version)会自动与配置文件中 "java.home"、"java.version" 属性绑定,
* 无需手动编写属性读取逻辑(由 Spring 自动完成)。
* 3. 容器注册:在 BeanPostProcessorCase 的 main 方法中通过 context.registerBean() 注册为单例 Bean,
* Spring 在刷新容器时会触发配置属性绑定逻辑(由 ConfigurationPropertiesBindingPostProcessor 处理)。
*/
@Data
@ConfigurationProperties(prefix = "java") // 绑定配置文件中以 "java." 为前缀的属性
static class BeanPostProcessorE {
/**
* 对应配置文件中的 java.home 属性(JDK 安装路径)
*/
private String home;
/**
* 对应配置文件中的 java.version 属性(JDK 版本号)
*/
private String version;
}
/**
* 测试类:用于演示依赖注入失败场景(依赖未注册的 Bean)
*/
@Slf4j
static class BeanPostProcessorH {
private BeanPostProcessorF beanPostProcessorF; // 未在容器中注册的 Bean
private BeanPostProcessorG beanPostProcessorG; // 未在容器中注册的 Bean
private String home;
@Autowired
public void setBeanPostProcessorF(BeanPostProcessorF beanPostProcessorF) {
log.info("[BeanPostProcessorH] @Autowired 生效,注入 BeanPostProcessorF: {}", beanPostProcessorF);
this.beanPostProcessorF = beanPostProcessorF;
}
@Resource
public void setBeanPostProcessorG(BeanPostProcessorG beanPostProcessorG) {
log.info("[BeanPostProcessorH] @Resource 生效,注入 BeanPostProcessorG: {}", beanPostProcessorG);
this.beanPostProcessorG = beanPostProcessorG;
}
@Autowired
public void setHome(@Value("${JAVA_HOME}") String home) {
log.info("[BeanPostProcessorH] @Value 生效,注入 JAVA_HOME: {}", home);
this.home = home;
}
@PostConstruct
public void init() {
log.info("[BeanPostProcessorH] @PostConstruct 生效,完成初始化");
}
@PreDestroy
public void destroy() {
log.info("[BeanPostProcessorH] @PreDestroy 生效,准备销毁");
}
@Override
public String toString() {
return "BeanPostProcessorH{" +
"beanPostProcessorF=" + beanPostProcessorF +
", beanPostProcessorG=" + beanPostProcessorG +
", home='" + home + '\'' +
'}';
}
}
}
package com.dwl.post_processor;
import com.dwl.json.JSON;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor;
import org.springframework.beans.factory.annotation.InjectionMetadata;
import org.springframework.beans.factory.config.DependencyDescriptor;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.ContextAnnotationAutowireCandidateResolver;
import org.springframework.core.MethodParameter;
import org.springframework.core.env.StandardEnvironment;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
/**
* @ClassName AutowiredPostProcessorCase
* @Description 手动模拟 Spring 对 @Autowired 注解的处理流程,
* 深入理解依赖注入元数据(InjectionMetadata)的生成和注入逻辑。
* <p>
* 关键方法对应 Spring 源码中的核心逻辑(如 AutowiredAnnotationBeanPostProcessor 的 postProcessProperties)。
* @Version 1.0.0
* @Date 2025
* @Author By Dwl
*/
@Slf4j
public class AutowiredPostProcessorCase {
/**
* 主方法:驱动整个手动模拟流程,验证 @Autowired 注入逻辑。
*/
public static void main(String[] args) throws Throwable {
// 1. 创建容器并注册基础 Bean(模拟已存在的 Bean)
log.info("[main] 1. 创建 DefaultListableBeanFactory 并注册基础 Bean...");
DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
// 注册单例 Bean(不会触发依赖注入,视为已初始化完成的成品 Bean)
// 对应 Spring 源码中的 {@link DefaultListableBeanFactory#registerSingleton(String, Object)}
factory.registerSingleton("beanPostProcessorB", new BeanPostProcessorCase.BeanPostProcessorB());
factory.registerSingleton("beanPostProcessorC", new BeanPostProcessorCase.BeanPostProcessorC());
factory.registerSingleton("beanPostProcessorF", new BeanPostProcessorCase.BeanPostProcessorF());
factory.registerSingleton("beanPostProcessorG", new BeanPostProcessorCase.BeanPostProcessorG());
log.info("[main] 1. 注册单例 Bean 后,singletonCount={}", factory.getSingletonCount());
// 2. 配置容器:支持 @Value 的 ${} 占位符解析
// 对应 Spring 源码中的 {@link DefaultListableBeanFactory#setAutowireCandidateResolver(AutowireCandidateResolver)}
log.info("[main] 2. 配置容器的自动装配解析器...");
factory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
// 3. 创建 AutowiredAnnotationBeanPostProcessor 并关联容器
// 对应 Spring 源码中的 {@link AutowiredAnnotationBeanPostProcessor#setBeanFactory(BeanFactory)}
log.info("[main] 3. 创建 AutowiredAnnotationBeanPostProcessor...");
AutowiredAnnotationBeanPostProcessor processor = new AutowiredAnnotationBeanPostProcessor();
processor.setBeanFactory(factory);
// ------------------------- 演示 BeanPostProcessorA 的 @Autowired 注入 -------------------------
// 目标 Bean:包含 @Autowired、@Resource、@Value 注解的 BeanPostProcessorA
BeanPostProcessorCase.BeanPostProcessorA beanA = new BeanPostProcessorCase.BeanPostProcessorA();
log.info("\n===== 开始处理 BeanPostProcessorA =====");
log.info("原始 Bean 状态(未注入): {}", beanA);
// 3.1 扫描 Bean 的 @Autowired 元数据(生成 InjectionMetadata)
// 对应 Spring 源码中的 {@link AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata(String, Class, PropertyValues)}
// 注意:findAutowiringMetadata 是私有方法,需通过反射调用
log.info("[main] 3.1 反射调用 findAutowiringMetadata...");
Method findAutowiringMetadataMethod = AutowiredAnnotationBeanPostProcessor.class.getDeclaredMethod(
"findAutowiringMetadata", String.class, Class.class, PropertyValues.class);
findAutowiringMetadataMethod.setAccessible(true);
InjectionMetadata injectionMetadata = (InjectionMetadata) findAutowiringMetadataMethod.invoke(
processor, "beanPostProcessorA", beanA.getClass(), null);
log.info("检测到 @Autowired 元素数量: {}", injectionMetadata.getInjectedElements().size());
// 3.2 执行依赖注入(按类型查找并设置属性/方法参数)
// 对应 Spring 源码中的 {@link AutowiredAnnotationBeanPostProcessor#postProcessProperties(PropertyValues, Object, String)}
log.info("[main] 3.2 执行依赖注入...");
processor.postProcessProperties(null, beanA, "beanPostProcessorA"); // 参数为 PropertyValues(此处无额外属性)
log.info("注入后 Bean 状态: {}", beanA);
// ------------------------- 演示 BeanPostProcessorH 的依赖注入 -------------------------
// 目标 Bean:包含 @Resource、@Value 注解的 BeanPostProcessorH
BeanPostProcessorCase.BeanPostProcessorH beanH = new BeanPostProcessorCase.BeanPostProcessorH();
log.info("\n===== 开始处理 BeanPostProcessorH =====");
log.info("原始 Bean 状态(未注入): {}", beanH);
// 4.1 手动注册 @Value 解析器(模拟 Spring 自动配置)
// 对应 Spring 源码中的 {@link ConfigurableApplicationContext#addEmbeddedValueResolver}
log.info("[main] 4.1 注册 @Value 解析器...");
factory.addEmbeddedValueResolver(new StandardEnvironment()::resolvePlaceholders);
// 4.2 扫描 Bean 的依赖元数据(包括 @Resource、@Value)
// 对应 Spring 源码中的 {@link AutowiredAnnotationBeanPostProcessor#findAutowiringMetadata(String, Class, PropertyValues)}
log.info("[main] 4.2 反射调用 findAutowiringMetadata...");
InjectionMetadata metadata = (InjectionMetadata) findAutowiringMetadataMethod.invoke(
processor, "beanPostProcessorH", beanH.getClass(), null);
log.info("检测到依赖元数据: {}", JSON.toJSON(metadata));
// 4.3 执行依赖注入(按字段和方法)
// 对应 Spring 源码中的 {@link InjectionMetadata#inject(Object, String, PropertyValues)}
log.info("[main] 4.3 执行 BeanPostProcessorH 的依赖注入...");
metadata.inject(beanH, "beanPostProcessorH", null);
log.info("注入后 BeanH 状态: {}", beanH);
// ------------------------- 验证依赖解析逻辑 -------------------------
log.info("\n===== 验证依赖解析逻辑 =====");
// 按字段解析依赖(BeanPostProcessorF)
Field fField = beanH.getClass().getDeclaredField("beanPostProcessorF");
DependencyDescriptor fDescriptor = new DependencyDescriptor(fField, false); // required=true
Object fObject = factory.doResolveDependency(fDescriptor, "beanPostProcessorH", null, null);
log.info("@Autowired 字段 beanPostProcessorF 解析结果: {}", fObject); // 应注入单例 BeanPostProcessorF
// 按方法参数解析依赖(BeanPostProcessorG)
Method gMethod = beanH.getClass().getDeclaredMethod("setBeanPostProcessorG", BeanPostProcessorCase.BeanPostProcessorG.class);
MethodParameter gParam = new MethodParameter(gMethod, 0);
DependencyDescriptor gDescriptor = new DependencyDescriptor(gParam, false);
Object gObject = factory.doResolveDependency(gDescriptor, "beanPostProcessorH", null, null);
log.info("@Resource 方法参数 beanPostProcessorG 解析结果: {}", gObject); // 应注入单例 BeanPostProcessorG
// 解析 @Value 注入(JAVA_HOME)
Method homeMethod = beanH.getClass().getDeclaredMethod("setHome", String.class);
MethodParameter homeParam = new MethodParameter(homeMethod, 0);
DependencyDescriptor homeDescriptor = new DependencyDescriptor(homeParam, false);
Object homeObject = factory.doResolveDependency(homeDescriptor, "beanPostProcessorH", null, null);
log.info("@Value 注入 JAVA_HOME 解析结果: {}", homeObject); // 应输出系统 JAVA_HOME 环境变量值
}
}