spring中的BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口,BeanFactoryPostProcessor的作用是在bean
的定義信息已經加載但還沒有初始化的時候執行方法postProcessBeanFactory()方法,而BeanDefinitionRegistryPostProcessor是在
BeanFactoryPostProcessor的前面執行。
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor { /** * Modify the application context's internal bean definition registry after its * standard initialization. All regular bean definitions will have been loaded, * but no beans will have been instantiated yet. This allows for adding further * bean definitions before the next post-processing phase kicks in. * @param registry the bean definition registry used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException; }
自定義一個實現了BeanDefinitionRegistryPostProcessor接口的MyBeanDefinitionRegistryPostProcessor 實現類,它會重寫
BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法和BeanFactoryPostProcessor的postProcessBeanFactory()方法
@Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
//BeanDefinitionRegistry可以給容器注冊bean System.out.println("MyBeanDefinitionRegistryPostProcessor...添加了foo之前的bean數="+registry.getBeanDefinitionCount()); RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(Foo.class); registry.registerBeanDefinition("helloFoo",rootBeanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { int beanDefinitionCount = beanFactory.getBeanDefinitionCount(); System.out.println("MyBeanDefinitionRegistryPostProcessor...postProcessBeanFactory...的bean數="+beanDefinitionCount); } }
配置類:
@Configuration @Import({MyBeanDefinitionRegistryPostProcessor.class}) public class ExtConfig { @Bean public Foo foo(){ return new Foo(); } }
foo類:
public class Foo { public Foo(){ System.out.println("bean的創建"); } @PostConstruct public void init(){ System.out.println("bean的初始化"); } @PreDestroy public void destroy(){ System.out.println("bean的銷毀"); } }
測試結果:
MyBeanDefinitionRegistryPostProcessor...添加了foo之前的bean數9 MyBeanDefinitionRegistryPostProcessor...postProcessBeanFactory...的bean數+10 bean的創建 bean的初始化 bean的創建 bean的初始化
debug:refresh()--》invokeBeanFactoryPostProcessors(),這里和注冊bean和beanFactory類似,按照優先級的的來進行。
// Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
invokeBeanDefinitionRegistryPostProcessors()方法:
/** * Invoke the given BeanDefinitionRegistryPostProcessor beans. */ private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); } }
最后去執行invokeBeanFactoryPostProcessors()方法;
/** * Invoke the given BeanFactoryPostProcessor beans. */ private static void invokeBeanFactoryPostProcessors( Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) { for (BeanFactoryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanFactory(beanFactory); } }
它獲取到所有的BeanFactoryPostProcessor 后,遍歷執行每一個具體的方法:在這里會去調用
MyBeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法: