Spring中處理Bean後置處理器BeanPostProcessor順序以及流程
執行順序
- 執行通過ApplicationContext新增進來的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
- 執行BeanFactory中實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
- 執行BeanFactory中實現了Ordered介面的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()
- 執行BeanFactory中其他的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
- 執行上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
- 執行通過ApplicationContext新增進來的BeanFactoryPostProcessor的postProcessBeanFactory()方法
- 執行BeanFactory中實現了PriorityOrdered介面的BeanFactoryPostProcessor的postProcessBeanFactory()方法
- 執行BeanFactory中實現了Ordered介面的BeanFactoryPostProcessor的postProcessBeanFactory()方法
- 執行BeanFactory中其他的BeanFactoryPostProcessor的postProcessBeanFactory()方法
簡單概括: Spring保證先執行 postProcessBeanDefinitionRegistry() 方法;
保證先執行通過手動新增進來的後置處理器,後執行程式碼實現的後置處理器
BeanDefinitionRegistryPostProcessor優先順序高於BeanFactoryPostProcessor
手動新增的BeanDefinitionRegistryPostProcessor》實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessor》實現了Ordered介面BeanDefinitionRegistryPostProcessor》其他的BeanDefinitionRegistryPostProcessor
》手動新增的BeanFactoryPostProcessor》實現了PriorityOrdered介面的BeanFactoryPostProcessor》實現了Ordered介面的BeanFactoryPostProcessor》其他的BeanFactoryPostProcessor
程式碼邏輯:
在Spring原始碼中,
AbstractApplicationContext的invokeBeanFactoryPostProcessors方法,核心原始碼貼出
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { // BeanDefinitionRegistryPostProcessor是一個特殊的BeanFactoryPostProcessor,需要先執行postProcessBeanDefinitionRegistry方法 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } // 儲存當前需要執行的實現了BeanDefinitionRegistryPostProcessor介面的後置處理器 // 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<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. // 首先,先執行實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 判斷這個類是否還實現了PriorityOrdered介面 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 這裡呼叫了getBean,所以生成一個BeanDefinitionRegistryPostProcessor的bean物件 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); // 執行postProcessBeanDefinitionRegistry方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. // 首先,先執行實現了Ordered介面的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法 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. // 最後,最後其他普通的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法 boolean reiterate = true; // 在一個BeanDefinitionRegistryPostProcessor中可以註冊另一個BeanDefinitionRegistryPostProcessor,所以需要遞迴找出所有的BeanDefinitionRegistryPostProcessor // 一個沒有實現PriorityOrdered介面的BeanDefinitionRegistryPostProcessor如果在內部註冊了一個實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessor,那麼就是沒有實現PriorityOrdered介面的先執行 while (reiterate) { reiterate = false; // 這裡會再一次拿到實現了PriorityOrdered介面或Ordered介面的BeanDefinitionRegistryPostProcessor,所以需要processedBeans進行過濾 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(); } //至此 所有的BeanFinition都已經註冊完成
其中,值得一提的是,下面貼出的原始碼:
// 在一個BeanDefinitionRegistryPostProcessor中可以註冊另一個BeanDefinitionRegistryPostProcessor,所以需要遞迴找出所有的BeanDefinitionRegistryPostProcessor // 一個沒有實現PriorityOrdered介面的BeanDefinitionRegistryPostProcessor如果在內部註冊了一個實現了PriorityOrdered介面的BeanDefinitionRegistryPostProcessor,那麼就是沒有實現PriorityOrdered介面的先執行 while (reiterate) { reiterate = false; // 這裡會再一次拿到實現了PriorityOrdered介面或Ordered介面的BeanDefinitionRegistryPostProcessor,所以需要processedBeans進行過濾 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(); }
這段程式碼考慮的是:當其餘“優先順序比較高的BeanFactoryPostProcessor”被註冊進BeanFactory以及呼叫的時候,也有可能會在postProcessBeanDefinitionRegistry方法或者postProcessBeanFactory方法中註冊新的BeanDefinitionRegistryPostProcessor,所以使用while迴圈的遞迴操作,找出以後操作中可能存在的新生成的BeanDefinitionRegistryPostProcessor,如果出現,將其註冊到BeanFactory中。