一: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, ListbeanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. // 如果存在BeanDefinitionRegistryPostProcessor类型对象,要先调用 Set processedBeans = new HashSet<>(); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List regularPostProcessors = new ArrayList<>(); List 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 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 priorityOrderedPostProcessors = new ArrayList<>(); List orderedPostProcessorNames = new ArrayList<>(); List 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 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 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对象。