一:BeanDefinitionRegistryPostProcessor 與BeanFactoryPostProcessor接口
這個接口支持自定義beanDefinition的注冊,在標准的注冊完成后(解析xml或者注解),在與實例化對象之前,實現這個接口
可以向beanDefinitionMap中注冊自定義的beanDefinition,這個接口從定義上看更多的是關注注冊。
1:實現beanDefinitionRegistryPostProcessor接口,重寫postProcessBeanDefinitionRegistry方法,在方法內創建beanDefinition對象,然后注冊到beanDefinitionRegistry中
創建一個pojo對象BeanDemo,用於測試在接口中注冊自定義beanDefinition
public class BeanDemo { private String name = "hello"; public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { final StringBuffer sb = new StringBuffer("BeanDemo{"); sb.append("name='").append(name).append('\''); sb.append('}'); return sb.toString(); } }
@Component public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException { System.out.println("MyBeanDefinitionRegistryPostProcessor: "+registry); // 向beanDefinitionMap中注冊自定義的beanDefinition對象 GenericBeanDefinition beanDefinition = new GenericBeanDefinition(); beanDefinition.setBeanClass(BeanDemo.class); registry.registerBeanDefinition("beanDemo",beanDefinition); } public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("MyBeanDefinitionRegistryPostProcessor: "+beanFactory); } }
成功的從spring容器中拿到了對象:
2:BeanFactoryPostProcessor接口
這個接口支持修改容器內的beanDefinition對象,也可以直接注冊bean對象,在標准的beanDefinition注冊之后以及預實例化bean對象之前
通過運行結果可以看出beanDefinition在postProcessBeanFactory方法中被修改:
在beanFactoryPostProcessor接口中注冊對象后,可以在spring中獲取到。
二:從源碼層面分析接口調用
refresh方法中invokeBeanFactoryPostProcessors:
主要的核心邏輯都在這個方法內:
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. // 如果存在BeanDefinitionRegistryPostProcessor類型對象,要先調用 Set<String> processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // 第一次進來beanFactoryPostProcessors集合為空,不會走進來 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } // 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. /** * 不要在這里初始化FactoryBean類型的對象,不要初始化post-Processor對象,要把 * PriorityOrdered類型和Ordered類型以及剩下的分開 */ List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. /** * 1: 根據類型找到所有實現BeanDefinitionRegistryPostProcessor接口的beanName * 2: 遍歷所有beanName,判斷是否是PriorityOrdered接口的實例 * 3: 如果是則 getBean實例化這個對象,然后放入processedBean集合中 * * 在這里getBeanNamesForType 會把字父類的beanDefinition合並Merge,得到RootBeanDefinition */ 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); } } /** * 1:對currentRegistryProcessors集合內實例對象排序 * 2: 將排序過的集合添加到注冊集合registryProcessors中 * 3:調用currentRegistryProcessors集合中對象方法 * 4:清空當前注冊對象集合currentRegistryProcessors */ sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); // 調用注冊對象方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. /** * 在這里步驟和上一步類似,只不過這里操作的是實現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. /** * 還是重復上面的動作,不過這次是排除掉上面已經調用過的實例(實現PriorityOrdered和Ordered接口) */ 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. /** * 在這里,調用上面已經處理過的所有處理器的postProcessBeanFactory回調方法 */ invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }
實例化並調用實現PriorityOrdered接口的BeanDefinitionRegistryPostProcessor實現對象:
調用接口:
實例化並調用實現Ordered接口的BeanDefinitionRegistryPostProcessor實現對象:
操作和剛才類似,只不過這次是調用實現Ordered接口的實現對象
實例化其他的BeanDefinitionRegistryPostProcessor實現對象:
因為BeanDefinitionRegistryPostProcessor接口繼承了 BeanFactoryPostProcessor接口,所以也是BeanFactoryPostProcessor的子類
把剛才已經調用過BeanDefinitionRegistryPostProcessor接口的對象,在調用BeanFactoryPostProcessor接口
到這里 實現BeanDefinitionRegistryPostProcessor接口的對象都調用了 BeanFactoryPostProcessor 的實現類,但是還有單獨只實現了 BeanFactoryPostProcessor 接口的,
而沒有實現 BeanDefinitionRegistryPostProcessor 的,也需要調用 postProcessorBeanFactory方法:
實例化並調用對象:
到這里所有實現BeanFactoryPostProcessor接口的類都實例化並調用過了。
總結:這兩個接口是在標准的加載解析,生成BeanDefinition對象完成注冊后,非懶加載的對象預實例化之前 ,預留的后置接口,支持自定義BeanDefinition
然后實現注冊,BeanDefinitionRegistryPostProcessor側重於注冊信息,BeanFactoryPostProcessor側重於修改BeanDefinition對象的信息,也可以直接注冊bean對象。