ApplicationContext 如何动态添加 Bean Definition
可以通过引入ImportBeanDefinitionRegistrar实现类,注册BeanDefinitionRegistryPostProcessor等方法动态添加bean definition,本文主要针对其使用方式做简要介绍,如果想了解具体的实现原理可以参考Spring Boot in Action - ConfigurationClassPostProcessor的处理逻辑-基于注解的bean定义加载过程。
建议采用ImportBeanDefinitionRegistrar方式,因为该方式比较正统。
1. 通过ImportBeanDefinitionRegistrar注册bean
1.1 step1:创建ImportBeanDefinitionRegistrar的实现类
public class CustomImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar, EnvironmentAware, BeanFactoryAware, BeanClassLoaderAware, ResourceLoaderAware {
private Logger logger = LoggerFactory.getLogger(CustomImportBeanDefinitionRegistrar.class);
private ClassLoader classLoader;
private BeanFactory beanFactory;
private Environment environment;
private ResourceLoader resourceLoader;
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// register your custom bean definition here
// here are some useful utils:
// org.springframework.boot.autoconfigure.AutoConfigurationPackages
// org.springframework.context.annotation.ClassPathBeanDefinitionScanner
// you can implement EnvironmentAware, BeanFactoryAware, BeanClassLoaderAware, ResourceLoaderAware as you need.
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
this.classLoader = classLoader;
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
}
@Override
public void setEnvironment(Environment environment) {
this.environment = environment;
}
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
}
1.2 step2: 配置你的实现类
@Configuration
@Import(CustomImportBeanDefinitionRegistrar.class)
public class CustomConfiguration {
}
2. 通过BeanDefinitionRegistryPostProcessor注册bean
step1: 定义BeanDefinitionRegistryPostProcessor的实现类,通过实现postProcessBeanDefinitionRegistry方法注册自己的bean。
step2: 添加@Componet注解注册CustomBeanDefinitionRegistryPostProcessor。
PS: 可以通过添加@PriorityOrdered,@Ordered注解提升优先级。
@Component
@Order
public class CustomBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
private Logger logger = LoggerFactory.getLogger(CustomBeanDefinitionRegistryPostProcessor.class);
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
// register your custom bean definition here
// here are some useful utils:
// org.springframework.boot.autoconfigure.AutoConfigurationPackages
// org.springframework.context.annotation.ClassPathBeanDefinitionScanner
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// do nothing
}
}