BeanDefinitionRegistryPostProcessor
BeanDefinitionRegistryPostProcessor扩展了BeanFactoryPostProcessor,提供Bean定义注册能力。
接口定义
Java
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
// 注册BeanDefinition
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
throws BeansException;
}
执行顺序
Java
┌─────────────────────────────────────┐
│ BeanDefinitionRegistryPostProcessor │
│ .postProcessBeanDefinitionRegistry │ ← 最先执行
├─────────────────────────────────────┤
│ BeanFactoryPostProcessor │
│ .postProcessBeanFactory │ ← 后执行
├─────────────────────────────────────┤
│ Bean实例化 │
└─────────────────────────────────────┘
动态注册BeanDefinition
Java
@Component
public class DynamicBeanRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 注册多个BeanDefinition
for (int i = 0; i < 5; i++) {
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClass(Worker.class);
bd.setScope("singleton");
bd.getConstructorArgumentValues()
.addGenericArgumentValue("worker-" + i);
registry.registerBeanDefinition("worker-" + i, bd);
}
System.out.println("注册5个Worker Bean");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 可在此修改已注册的BeanDefinition
}
}
条件性注册
Java
@Component
public class ConditionalBeanRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 检查环境变量决定是否注册
if (System.getenv("ENABLE_CACHE") != null) {
registerCacheBeans(registry);
}
// 检查配置决定注册策略
String strategy = System.getProperty("db.strategy", "mysql");
registerDatabaseStrategy(registry, strategy);
}
private void registerCacheBeans(BeanDefinitionRegistry registry) {
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClassName("com.example.RedisCacheService");
registry.registerBeanDefinition("cacheService", bd);
}
private void registerDatabaseStrategy(BeanDefinitionRegistry registry,
String strategy) {
String className = "com.example." + strategy + "DataSource";
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClassName(className);
registry.registerBeanDefinition("dataSource", bd);
}
}
BeanDefinitionRegistry API
Java
// 注册BeanDefinition
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition);
// 移除BeanDefinition
void removeBeanDefinition(String beanName);
// 获取BeanDefinition
BeanDefinition getBeanDefinition(String beanName);
// 判断是否包含
boolean containsBeanDefinition(String beanName);
// 获取BeanDefinition数量
int getBeanDefinitionCount();
// 获取所有Bean名称
String[] getBeanDefinitionNames();
扫描并注册
Java
@Component
public class ComponentScannerRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 自定义扫描逻辑
ClassPathBeanDefinitionScanner scanner =
new ClassPathBeanDefinitionScanner(registry);
// 添加过滤器
scanner.addIncludeFilter(
new AnnotationTypeFilter(MyComponent.class));
// 扫描指定包
scanner.scan("com.example.plugins");
}
}
ImportBeanDefinitionRegistrar对比
Java
// 通过@Import方式注册
@Import(MyRegistrar.class)
@Configuration
public class AppConfig { }
public class MyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata metadata,
BeanDefinitionRegistry registry) {
// 注册BeanDefinition
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setBeanClass(MyService.class);
registry.registerBeanDefinition("myService", bd);
}
}
| 方式 | 注册时机 | 特点 |
|---|---|---|
| BeanDefinitionRegistryPostProcessor | 容器启动时 | 实现类自动执行 |
| ImportBeanDefinitionRegistrar | @Import触发 | 需配合注解使用 |
动态代理Bean注册
text
@Component
public class RpcServiceRegistrar implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// 扫描RPC接口
ClassPathScanningCandidateComponentProvider scanner =
new ClassPathScanningCandidateComponentProvider(false);
scanner.addIncludeFilter(new AnnotationTypeFilter(RpcService.class));
for (BeanDefinition bd : scanner.findCandidateComponents("com.example.rpc")) {
String className = bd.getBeanClassName();
// 创建FactoryBean定义
GenericBeanDefinition factoryBd = new GenericBeanDefinition();
factoryBd.setBeanClass(RpcServiceFactoryBean.class);
factoryBd.getConstructorArgumentValues()
.addGenericArgumentValue(className);
String beanName = generateBeanName(className);
registry.registerBeanDefinition(beanName, factoryBd);
}
}
}
与BeanFactoryPostProcessor对比
| 接口 | 执行时机 | 功能 |
|---|---|---|
| BeanDefinitionRegistryPostProcessor | 最先 | 注册BeanDefinition |
| BeanFactoryPostProcessor | 其次 | 修改BeanDefinition |
BeanDefinitionRegistryPostProcessor优先级更高,可注册新Bean。
要点总结
- 继承BeanFactoryPostProcessor,优先执行
- postProcessBeanDefinitionRegistry用于注册Bean
- postProcessBeanFactory用于修改已注册Bean
- 执行顺序在标准BeanFactoryPostProcessor之前
- 适合动态注册大量Bean的场景
📝 发现内容有误?点击此处直接编辑