动态注册Bean、删除Bean
Spring容器初始化时,从资源中读取到bean的相关定义后,保存在BeanDefinitionMap,在实例化bean的操作就是依据这些bean的定义来做的,而在实例化之前,Spring允许我们通过自定义扩展来改变bean的定义,定义一旦变了,后面的实例也就变了,而beanFactory后置处理器,即BeanFactoryPostProcessor就是用来改变bean定义的
BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor的实现类在其postProcessBeanFactory方法被调用时,可以对bean的定义进行控制,因此BeanDefinitionRegistryPostProcessor的实现类一共要实现以下两个方法:
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException: 该方法的实现中,主要用来对bean定义做一些改变。
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException: 该方法用来注册更多的bean到spring容器中,详细观察入参BeanDefinitionRegistry接口,看看这个参数能带给我们什么能力。
从BeanDefinitionRegistry可以看到,BeanDefinitionRegistry提供了丰富的方法来操作BeanDefinition,判断、注册、移除等方法都准备好了,我们在编写postProcessBeanDefinitionRegistry方法的内容时,就能直接使用入参registry的这些方法来完成判断和注册、移除等操作。
org.springframework.context.support.AbstractApplicationContext#refresh中的invokeBeanFactoryPostProcessors(beanFactory);用来找出所有beanFactory后置处理器,并且调用这些处理器来改变bean的定义。
invokeBeanFactoryPostProcessors(beanFactory)实际上是委托org.springframework.context.support.PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());方法处理的。
所有实现了BeanDefinitionRegistryPostProcessor接口的bean,其postProcessBeanDefinitionRegistry方法都会调用,然后再调用其postProcessBeanFactory方法,这样一来,我们如果自定义了BeanDefinitionRegistryPostProcessor接口的实现类,那么我们开发的postProcessBeanDefinitionRegistry和postProcessBeanFactory方法都会被执行一次
实战代码
@Component
public class AnnotationScannerConfigurer implements BeanDefinitionRegistryPostProcessor {
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(TestServiceImpl.class);
beanDefinitionRegistry.registerBeanDefinition("testService", rootBeanDefinition);
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
Map<String, Object> beanMap = configurableListableBeanFactory.getBeansWithAnnotation(AutoDiscoverClass.class);
}
总结下,BeanFactoryPostProcessor可以修改各个注册的Bean,BeanDefinitionRegistryPostProcessor可以动态将Bean注册。
|