标签(空格分隔): Spring
之前写过关于Spring总动态注册Bean的两篇文章 Spring动态注册bean 动态注册bean,Spring官方套路:使用ImportBeanDefinitionRegistrar
这里再介绍一个Spring官方大量使用的接口BeanDefinitionRegistryPostProcessor,这个接口扩展自BeanFactoryPostProcessor,专门用于动态注册Bean。 此外,Spring5中的BeanDefinitionBuilder还增加了一个新的genericBeanDefinition方法,签名如下:
public static <T> BeanDefinitionBuilder genericBeanDefinition(
@Nullable Class<T> beanClass, Supplier<T> instanceSupplier)
可以看到,此处在会用Supplier接口的返回值作为bean的实例。 这样就提供了替代传统的static和instance factory-mehtod的功能,前面两者分别需要调用BeanDefinitionBuilder#setFactoryMethod和BeanDefinitionBuilder#setFactoryMethodOnBean专门进行配置。
因为这里要使用Spring5,所以Spring Boot要使用2.x版本,编写该文章时,最新版本为2.0.0.M5,该依赖并没有发布到maven**仓库中,需要手工添加Spring的仓库,如下:
...省略
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.0.M5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
<pluginRepositories>
<pluginRepository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</pluginRepository>
<pluginRepository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</pluginRepository>
</pluginRepositories>
...省略
核心代码如下:
@Component
@Slf4j
public class PersonBeanDefinitionRegistryPostProcessor
implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)
throws BeansException {
// 注册Bean定义,容器根据定义返回bean
log.info("register personManager1>>>>>>>>>>>>>>>>");
//构造bean定义
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
.genericBeanDefinition(PersonManager.class);
//设置依赖
beanDefinitionBuilder.addPropertyReference("personDao", "personDao");
BeanDefinition personManagerBeanDefinition = beanDefinitionBuilder
.getRawBeanDefinition();
//注册bean定义
registry.registerBeanDefinition("personManager1", personManagerBeanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)
throws BeansException {
// 注册Bean实例,使用supply接口
log.info("register personManager2>>>>>>>>>>>>>>>>");
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder
.genericBeanDefinition(PersonManager.class, () -> {
PersonDao personDao = beanFactory.getBean(PersonDao.class);
PersonManager personManager = new PersonManager();
personManager.setPersonDao(personDao);
return personManager;
});
BeanDefinition personManagerBeanDefinition = beanDefinitionBuilder
.getRawBeanDefinition();
((DefaultListableBeanFactory) beanFactory)
.registerBeanDefinition("personManager2", personManagerBeanDefinition);
}
}
完整代码:https://github.com/pkpk1234/BeanDefinitionRegistryPostProcessor-Demo
官方例子: Spring ConfigurationClassPostProcessor
Spring Cloud RefreshAutoConfiguration GenericScope