此文是 【Spring 容器详解】-> 【【附录】Spring容器的启动过程】的支节点。
在Spring容器的启动过程中,AbstractApplicationContext.refresh()方法的第五个步骤是invokeBeanFactoryPostProcessors()。这个方法负责调用所有已注册的BeanFactoryPostProcessor,这些处理器可以在Bean定义加载完成后、Bean实例化之前对BeanFactory进行修改,是Spring框架中非常重要的扩展点。
1. invokeBeanFactoryPostProcessors()方法在refresh()流程中的位置
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1. 准备刷新
prepareRefresh();
// 2. 获取BeanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3. 准备BeanFactory
prepareBeanFactory(beanFactory);
try {
// 4. 允许子类在标准初始化后修改BeanFactory
postProcessBeanFactory(beanFactory);
// 5. 调用BeanFactoryPostProcessor - 本文重点分析的方法
invokeBeanFactoryPostProcessors(beanFactory);
// 6. 注册BeanPostProcessor
registerBeanPostProcessors(beanFactory);
// 后续步骤...
} catch (BeansException ex) {
// 异常处理
}
}
}
2. invokeBeanFactoryPostProcessors()方法源码分析
2.1 方法签名和基本结构
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 获取所有BeanFactoryPostProcessor
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
}
方法分析:
- 参数:
ConfigurableListableBeanFactory beanFactory- 可配置的可列出的Bean工厂 - 主要功能:调用所有已注册的BeanFactoryPostProcessor
- 设计目的:在Bean实例化之前对BeanFactory进行修改和增强
2.2 核心执行逻辑
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// 1. 调用BeanFactoryPostProcessor
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 处理BeanFactoryPostProcessor
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
// 2. 调用BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// 获取实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 获取实现了Ordered接口的BeanDefinitionRegistryPostProcessor
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// 获取其他的BeanDefinitionRegistryPostProcessor
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 3. 调用BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
} else {
// 如果不是BeanDefinitionRegistry,直接调用BeanFactoryPostProcessor
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
// 4. 获取并调用其他的BeanFactoryPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// 按优先级排序并调用
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
continue;
}
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
} else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// 调用PriorityOrdered的BeanFactoryPostProcessor
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 调用Ordered的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String ppName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// 调用其他的BeanFactoryPostProcessor
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String ppName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// 清除缓存
beanFactory.clearMetadataCache();
}
3. BeanFactoryPostProcessor的类型和层次结构
3.1 BeanFactoryPostProcessor接口
public interface BeanFactoryPostProcessor {
/**
* 在标准BeanFactory初始化后修改BeanFactory
* 此时所有的Bean定义都已加载,但Bean实例还未创建
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
作用:
- 在BeanFactory初始化完成后、Bean实例化之前被调用
- 可以修改Bean定义、添加新的Bean定义
- 不能修改Bean实例,因为此时Bean还未创建
3.2 BeanDefinitionRegistryPostProcessor接口
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* 在标准BeanFactory初始化后修改BeanDefinitionRegistry
* 此时可以添加、修改、删除Bean定义
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
作用:
- 继承自BeanFactoryPostProcessor
- 在Bean定义注册阶段被调用
- 可以动态注册新的Bean定义
- 执行优先级高于BeanFactoryPostProcessor
3.3 执行顺序和优先级
// 执行顺序(从高到低)
1. BeanDefinitionRegistryPostProcessor (PriorityOrdered)
2. BeanDefinitionRegistryPostProcessor (Ordered)
3. BeanDefinitionRegistryPostProcessor (其他)
4. BeanFactoryPostProcessor (PriorityOrdered)
5. BeanFactoryPostProcessor (Ordered)
6. BeanFactoryPostProcessor (其他)
4. 内置的BeanFactoryPostProcessor详解
4.1 ConfigurationClassPostProcessor
作用:
- 处理@Configuration注解的配置类
- 解析@ComponentScan、@Import、@Bean等注解
- 生成Bean定义并注册到容器中
实际应用:
@Configuration
@ComponentScan("com.example")
@Import(OtherConfig.class)
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
// ConfigurationClassPostProcessor会:
// 1. 扫描com.example包下的所有类
// 2. 识别@Component、@Service、@Repository等注解
// 3. 处理@Import导入的配置类
// 4. 解析@Bean方法并生成Bean定义
4.2 PropertySourcesPlaceholderConfigurer
作用:
- 处理占位符${...}的解析
- 从属性文件、环境变量等来源获取值
- 替换Bean定义中的占位符
实际应用:
// 属性文件 application.properties
db.url=jdbc:mysql://localhost:3306/test
db.username=root
db.password=123456
// Bean定义中使用占位符
@Component
public class DatabaseConfig {
@Value("${db.url}")
private String url;
@Value("${db.username}")
private String username;
@Value("${db.password}")
private String password;
}
// PropertySourcesPlaceholderConfigurer会:
// 1. 加载属性文件
// 2. 解析占位符${db.url}等
// 3. 用实际值替换占位符
4.3 PropertyOverrideConfigurer
作用:
- 覆盖Bean属性的默认值
- 支持外部配置覆盖内部配置
- 常用于不同环境的配置管理
实际应用:
// 属性文件 override.properties
userService.maxUsers=200
userService.timeout=5000
// Bean定义
@Component
public class UserService {
private int maxUsers = 100; // 默认值
private long timeout = 3000; // 默认值
// getter和setter方法
}
// PropertyOverrideConfigurer会:
// 1. 读取override.properties文件
// 2. 将userService.maxUsers=200转换为属性注入
// 3. 覆盖Bean的默认值
5. 自定义BeanFactoryPostProcessor实现
5.1 基础实现示例
@Component
public class CustomBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("CustomBeanFactoryPostProcessor被调用");
// 获取所有Bean定义名称
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
// 修改Bean定义
if (beanDefinition.getBeanClassName() != null &&
beanDefinition.getBeanClassName().contains("Service")) {
// 修改作用域
beanDefinition.setScope(BeanDefinition.SCOPE_PROTOTYPE);
// 添加属性值
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
propertyValues.addPropertyValue("customProperty", "customValue");
System.out.println("修改了Bean: " + beanName);
}
}
}
}
5.2 动态注册Bean定义
@Component
public class DynamicBeanRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("DynamicBeanRegistrar被调用");
// 动态创建Bean定义
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(DynamicService.class);
beanDefinition.setScope(BeanDefinition.SCOPE_SINGLETON);
// 设置属性值
MutablePropertyValues propertyValues = new MutablePropertyValues();
propertyValues.addPropertyValue("name", "动态创建的Bean");
beanDefinition.setPropertyValues(propertyValues);
// 注册Bean定义
registry.registerBeanDefinition("dynamicService", beanDefinition);
System.out.println("动态注册了Bean: dynamicService");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("DynamicBeanRegistrar的postProcessBeanFactory被调用");
}
}
// 动态创建的Bean类
public class DynamicService {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void doSomething() {
System.out.println("DynamicService: " + name);
}
}
5.3 条件化Bean注册
@Component
public class ConditionalBeanRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 检查环境条件
String profile = System.getProperty("spring.profiles.active", "dev");
if ("prod".equals(profile)) {
// 生产环境注册生产相关的Bean
registerProductionBeans(registry);
} else if ("dev".equals(profile)) {
// 开发环境注册开发相关的Bean
registerDevelopmentBeans(registry);
}
}
private void registerProductionBeans(BeanDefinitionRegistry registry) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(ProductionService.class);
registry.registerBeanDefinition("productionService", beanDefinition);
}
private void registerDevelopmentBeans(BeanDefinitionRegistry registry) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(DevelopmentService.class);
registry.registerBeanDefinition("developmentService", beanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 可以在这里进行Bean定义的修改
}
}
6. 实际应用场景
6.1 配置属性加密解密
@Component
public class EncryptedPropertyPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
MutablePropertyValues propertyValues = beanDefinition.getPropertyValues();
// 遍历所有属性值
PropertyValue[] propertyValueArray = propertyValues.getPropertyValues();
for (PropertyValue propertyValue : propertyValueArray) {
Object value = propertyValue.getValue();
if (value instanceof String && ((String) value).startsWith("ENC(")) {
// 解密加密的属性值
String encryptedValue = (String) value;
String decryptedValue = decrypt(encryptedValue);
// 替换属性值
propertyValues.setPropertyValue(propertyValue.getName(), decryptedValue);
}
}
}
}
private String decrypt(String encryptedValue) {
// 解密逻辑
String encrypted = encryptedValue.substring(4, encryptedValue.length() - 1);
return "decrypted_" + encrypted; // 简化的解密逻辑
}
}
// 使用加密属性
@Component
public class DatabaseConfig {
@Value("${db.password}")
private String password; // 实际值可能是 ENC(encrypted_password)
}
6.2 动态数据源配置
@Component
public class DynamicDataSourcePostProcessor implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// 读取配置文件获取数据源配置
Properties dataSourceProps = loadDataSourceProperties();
// 为每个数据源创建Bean定义
for (String dataSourceName : dataSourceProps.stringPropertyNames()) {
if (dataSourceName.startsWith("datasource.")) {
String dsName = dataSourceName.substring("datasource.".length());
registerDataSource(registry, dsName, dataSourceProps);
}
}
}
private void registerDataSource(BeanDefinitionRegistry registry, String name, Properties props) {
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(DataSource.class);
beanDefinition.setFactoryMethodName("createDataSource");
// 设置工厂方法参数
ConstructorArgumentValues constructorArgs = new ConstructorArgumentValues();
constructorArgs.addIndexedArgumentValue(0, props.getProperty("datasource." + name + ".url"));
constructorArgs.addIndexedArgumentValue(1, props.getProperty("datasource." + name + ".username"));
constructorArgs.addIndexedArgumentValue(2, props.getProperty("datasource." + name + ".password"));
beanDefinition.setConstructorArgumentValues(constructorArgs);
registry.registerBeanDefinition(name + "DataSource", beanDefinition);
}
private Properties loadDataSourceProperties() {
Properties props = new Properties();
try {
props.load(getClass().getClassLoader().getResourceAsStream("datasource.properties"));
} catch (IOException e) {
throw new RuntimeException("加载数据源配置失败", e);
}
return props;
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 可以在这里进行数据源Bean的进一步配置
}
}
6.3 性能监控和统计
@Component
public class PerformanceMonitorPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
// 为Service层的Bean添加性能监控
if (isServiceBean(beanDefinition)) {
addPerformanceMonitoring(beanDefinition);
}
}
}
private boolean isServiceBean(BeanDefinition beanDefinition) {
String className = beanDefinition.getBeanClassName();
return className != null &&
(className.contains("Service") || className.contains("Controller"));
}
private void addPerformanceMonitoring(BeanDefinition beanDefinition) {
// 添加BeanPostProcessor来监控性能
// 这里可以通过修改Bean定义来添加性能监控功能
System.out.println("为Bean添加性能监控: " + beanDefinition.getBeanClassName());
}
}
7. 性能优化和最佳实践
7.1 执行顺序优化
@Component
public class OptimizedPostProcessor implements BeanFactoryPostProcessor, PriorityOrdered {
@Override
public int getOrder() {
return Ordered.HIGHEST_PRECEDENCE; // 最高优先级
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 优先执行的逻辑
System.out.println("OptimizedPostProcessor优先执行");
}
}
7.2 条件化执行
@Component
public class ConditionalPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 检查是否在特定环境下执行
if (shouldExecute()) {
doProcess(beanFactory);
}
}
private boolean shouldExecute() {
String profile = System.getProperty("spring.profiles.active", "dev");
return "prod".equals(profile);
}
private void doProcess(ConfigurableListableBeanFactory beanFactory) {
// 实际的处理逻辑
System.out.println("在生产环境下执行特殊处理");
}
}
7.3 缓存和复用
@Component
public class CachedPostProcessor implements BeanFactoryPostProcessor {
private final Map<String, Object> cache = new ConcurrentHashMap<>();
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
String[] beanNames = beanFactory.getBeanDefinitionNames();
for (String beanName : beanNames) {
// 使用缓存避免重复计算
Object cachedResult = cache.get(beanName);
if (cachedResult == null) {
cachedResult = processBean(beanName, beanFactory);
cache.put(beanName, cachedResult);
}
}
}
private Object processBean(String beanName, ConfigurableListableBeanFactory beanFactory) {
// 处理Bean的逻辑
return "processed_" + beanName;
}
}
8. 异常处理和调试
8.1 常见异常类型
8.1.1 BeanDefinitionStoreException
try {
context.refresh();
} catch (BeanDefinitionStoreException e) {
System.err.println("Bean定义存储异常: " + e.getMessage());
System.err.println("资源位置: " + e.getResourceDescription());
// 处理异常
}
8.1.2 BeanCreationException
try {
context.refresh();
} catch (BeanCreationException e) {
System.err.println("Bean创建异常: " + e.getMessage());
System.err.println("Bean名称: " + e.getBeanName());
// 处理异常
}
8.2 调试技巧
@Component
public class DebugPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 打印所有Bean定义信息
String[] beanNames = beanFactory.getBeanDefinitionNames();
System.out.println("=== Bean定义信息 ===");
for (String beanName : beanNames) {
BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName);
System.out.println("Bean名称: " + beanName);
System.out.println("Bean类: " + beanDefinition.getBeanClassName());
System.out.println("作用域: " + beanDefinition.getScope());
System.out.println("是否单例: " + beanDefinition.isSingleton());
System.out.println("是否原型: " + beanDefinition.isPrototype());
System.out.println("---");
}
}
}
总结
invokeBeanFactoryPostProcessors()方法的核心作用
- Bean定义修改:在Bean实例化之前修改Bean定义
- 动态Bean注册:动态添加新的Bean定义到容器中
- 配置处理:处理各种配置注解和属性文件
- 扩展机制:为Spring框架提供强大的扩展能力
方法的重要性
- 配置处理:处理@Configuration、@ComponentScan等注解
- 属性解析:解析占位符和属性文件
- 动态扩展:支持运行时动态注册Bean
- 环境适配:支持不同环境的配置管理
最佳实践建议
- 合理使用优先级:通过PriorityOrdered和Ordered控制执行顺序
- 条件化执行:根据环境条件决定是否执行
- 性能优化:避免在PostProcessor中执行耗时操作
- 异常处理:妥善处理可能出现的异常情况
- 缓存机制:对于重复计算的结果考虑使用缓存
invokeBeanFactoryPostProcessors()方法是Spring容器启动流程中的关键步骤,它为Spring框架提供了强大的扩展能力,允许在Bean实例化之前对容器进行修改和增强。