之前有写过一篇文章【设计模式】基于SpringBoot实现的策略模式 ,通过策略模式可以实现对于不同的参数,调用不同的bean,实现对于代码的最少侵入。基于这种方式,可以通过读取配置文件,注入到bean中,实现多个bean的配置方法。但是这种方式存在的问题就是:
- 配置文件每增加一个配置,需要增加一个bean配置类。
- 多个配置增加的时候容易遗漏,容易出错。
因此,本文将针对这种情况,基于BeanDefinitionRegistryPostProcessor实现配置文件读取动态注入多个Bean。
一、BeanDefinitionRegistryPostProcessor简介
BeanDefinitionRegistryPostProcessor即实现postProcessBeanDefinitionRegistry方法,可以修改增加BeanDefinition。
此特性可以用来动态生成bean,比如读取某个配置项,然后根据配置项动态生成bean。
spring中的容器其实就是 Beanfactory 中的一个 Map,key 是 Bean 的名称,value 是 Bean 对应的 BeanDefinition,这个注册 Bean 的方法由 BeanFactory 子类实现。
BeanDefinition 用于保存 Bean 的相关信息,包括属性、构造方法参数、依赖的 Bean 名称及是否单例、延迟加载等,它是实例化 Bean 的原材料,Spring 就是根据 BeanDefinition 中的信息实例化 Bean。
二、实现方式
首先是需要自定义实现类,实现BeanDefinitionRegistryPostProcessor以及EnvironmentAware。本文中还实现了ApplicationContextAware 接口,为的是重新获取已经注册的bean,如果没有这个需求是可以不实现的。
ApplicationContextAware 获取的对象是 ApplicationContext。 其继承了 Aware 接口,并定义一个 set 方法,参数就是 ApplicationContext 对象。
1. 核心代码实现:
/**
* RestService根据配置自动注入Bean
*
* @author: xxx
* @date: 2020-09-11 9:28
* ApplicationContextAware 是为了重新获取bean而实现,不用可以不添加,后续会说明
*/
@Component
@Slf4j
public class RestServiceBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor, EnvironmentAware, ApplicationContextAware {
privat