BeanFactoryPostProcessor是BeanFactory的一个钩子接口,更是一种扩展,也正是因为这个接口造就了spring加载Bean的方式变得多种多样。我相信大部分开发人员对这个接口可能还存在一些陌生,毕竟这个接口是属于一种底层扩展,如果你是一个spring插件开发者,那一定对这个接口很熟悉。本文从源码的角度来分析spring是如何通过BeanDefinitionRegistryPostProcessor来加载Bean。
我们从源码查看BeanFactoryPostProcessor的层次结构,发现它还有一个子接口BeanDefinitionRegistryPostProcessor,代码结构如下:
@FunctionalInterface public interface BeanFactoryPostProcessor { /** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
根据源码我们知道只有一个方法postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory),我们是通过这个BeanFactory来增强BeanFactory的功能。
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; }
根据源码我们知道只有一个方法postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry),这个方法很明显是为了Bean的注册而生了,BeanDefinitionRegistry 是BeanDefinition的注册器,而注册Bean的过程是将满足Bean条件的类解析为BeanDefinition对象然后注册到BeanDefinition注册器中。
BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor都是扩展Bean的加载方式,当我们需要自定义自己的Bean加载方式时实现BeanDefinitionRegistryPostProcessor接口即可。@Configuration注解的实现就是基于BeanDefinitionRegistryPostProcessor接口完成。
看过spring源码的读者都很清楚AbstractApplicationContext类中refresh()是spring加载Bean的核心方法,大部分的处理逻辑都是在这个方法中完成,代码如下:
@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh"); // Prepare this context for refreshing. /** * 准备上下文刷新工作,如设置初始值 */ prepareRefresh(); // Tell the subclass to refresh the internal bean factory. /** * 告诉子类刷新内部beanFactory,返回Bean工厂 */ ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. /** * 准备beanFactory,以便于上下文中使用 */ prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. /** * 允许在上下文子类中对bean工厂进行后处理。 */ postProcessBeanFactory(beanFactory); /** * 开启处理PostProcessors步骤器 */ StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process"); // Invoke factory processors registered as beans in the context. /** * 调用BeanFactory的后置处理器 */ invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. /** * * 注册拦截bean创建的bean处理器 */ registerBeanPostProcessors(beanFactory); /** * 处理PostProcessors步骤器 */ beanPostProcess.end(); // Initialize message source for this context. /** * 初始化MessageSource */ initMessageSource(); // Initialize event multicaster for this context. /** * 初始化Application监听器的管理Bean(ApplicationEventMulticaster) */ initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. /** * 模板模式,刷新Bean的操作,由子类实现具体逻辑 */ onRefresh(); // Check for listener beans and register them. /** * 检查和注册监听器 */ registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. /** * 实例化所有(非惰性初始化)单例 */ finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. /** * 发布相应的事件 */ finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. destroyBeans(); // Reset 'active' flag. cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... resetCommonCaches(); contextRefresh.end(); } } }
根据源码发现spring在invokeBeanFactoryPostProcessors(beanFactory)方法中是实现BeanFactoryPostProcessors的具体逻辑,下面根据这个方法来分析处理逻辑。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { /** * 执行BeanFactoryPostProcessor,是该方法的处理核心 */ PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) /** * 检查和赋初始值 */ if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
逻辑处理核心是PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())方法,下面分析:
public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { Set<String> processedBeans = new HashSet<>(); /** * 首先调用BeanDefinitionRegistryPostProcessors(如果有)。 */ if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; /** * 用于存放BeanFactoryPostProcessor的对象 */ List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); /** * 用户存放BeanDefinitionRegistryPostProcessor对象 */ List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); /********************************* 下面处理BeanDefinitionRegistryPostProcessor逻辑 *************************************/ /** * 遍历最原始的BeanFactoryPostProcessor列表,找出BeanDefinitionRegistryPostProcessor和 BeanFactoryPostProcessor * BeanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口 */ for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; /** * 执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry */ registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } /** * 定义当前找到的BeanDefinitionRegistryPostProcessor临时存储 */ List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. // 首先,调用实现PriorityOrdered的BeanDefinitionRegistryPostProcessor。 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, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear(); // 接下来,调用实现Ordered的BeanDefinitionRegistryPostProcessor。 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, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear(); // 最后,调用所有其他BeanDefinitionRegistryPostProcessor,直到不再出现其他BeanDefinitionRegistryPostProcessor。 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, beanFactory.getApplicationStartup()); currentRegistryProcessors.clear(); } /** * 批量执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry */ invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); /** * 批量执行BeanFactoryPostProcessor(最开始的BeanFactoryPostProcessor) */ invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } /********************************* 下面处理BeanFactoryPostProcessor逻辑(可能执行上面步骤产生新的BeanFactoryPostProcessor),执行逻辑和BeanDefinitionRegistryPostProcessor一致 *************************************/ // 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<>(orderedPostProcessorNames.size()); 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<>(nonOrderedPostProcessorNames.size()); 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(); } /** * 排序BeanFactoryPostProcessor * @param postProcessors * @param beanFactory */ private static void sortPostProcessors(List<?> postProcessors, ConfigurableListableBeanFactory beanFactory) { // Nothing to sort? if (postProcessors.size() <= 1) { return; } Comparator<Object> comparatorToUse = null; if (beanFactory instanceof DefaultListableBeanFactory) { comparatorToUse = ((DefaultListableBeanFactory) beanFactory).getDependencyComparator(); } if (comparatorToUse == null) { comparatorToUse = OrderComparator.INSTANCE; } postProcessors.sort(comparatorToUse); } /** * 执行 BeanDefinitionRegistryPostProcessor * @param postProcessors * @param registry * @param applicationStartup */ private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process") .tag("postProcessor", postProcessor::toString); postProcessor.postProcessBeanDefinitionRegistry(registry); postProcessBeanDefRegistry.end(); } } /** * 执行invokeBeanFactoryPostProcessors * @param postProcessors * @param beanFactory */ private static void invokeBeanFactoryPostProcessors( Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) { for (BeanFactoryPostProcessor postProcessor : postProcessors) { StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process") .tag("postProcessor", postProcessor::toString); postProcessor.postProcessBeanFactory(beanFactory); postProcessBeanFactory.end(); } }
上面是spring执行BeanFactoryPostProcessor的具体逻辑,执行流程非常清晰,执行步骤如下:
第一步 :遍历最原始的BeanFactoryPostProcessor,找到BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor,且执行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry(registry)方法加载Bean。
第二步 :从BeanFactory中寻找BeanDefinitionRegistryPostProcessor的PriorityOrdered(最高优先级的排序)类型Bean,排序后执行postProcessBeanDefinitionRegistry(registry)方法加载Bean。
第三步 :从BeanFactory中寻找BeanDefinitionRegistryPostProcessor未被加载的Ordered(排序)类型Bean,排序后执行postProcessBeanDefinitionRegistry(registry)方法加载Bean。
第四步 :从BeanFactory中寻找出未被加载的BeanDefinitionRegistryPostProcessor类型Bean,然后执行postProcessBeanDefinitionRegistry(registry)方法加载Bean,这一步目的就是处理加载新的BeanDefinitionRegistryPostProcessor的Bean。
第五步 :从BeanFactory中寻找BeanFactoryPostProcessor的PriorityOrdered(最高优先级的排序)类型Bean,排序后执行postProcessBeanFactory(beanFactory)方法加载Bean。
第六步 :从BeanFactory中寻找BeanFactoryPostProcessor未被加载的Ordered(排序)的类型Bean,排序后执行postProcessBeanFactory(beanFactory)方法加载Bean。
第七步 :从BeanFactory中寻找出未排序的BeanFactoryPostProcessor类型Bean,然后执行postProcessBeanFactory(beanFactory)方法加载Bean。
BeanFactoryPostProcessor是执行最早的后置处理器,了解其原理对我们开发spring插件有很大的帮助,特别是BeanDefinitionRegistryPostProcessor接口对外扩展spring加载Bean的多样化。希望通过源码的角度帮助读者知其然更知其所以然。