Spring source code (7) - post-processor

A brief review of the previous article shows that after the BeanFacroty is created, you can use Editor and EditorRegistrar to implement custom extensions to class attributes and ignore the Aware interface to be automatically assembled.
This post will follow the refresh() main process method and execute it downwards. Before talking about the specific logic of the invokeBeanFactoryPostProcessors method, let's briefly introduce the BeanFactoryPostProcessor interface and the execution process of the entire invokeBeanFactoryPostProcessors method.

refresh

public void refresh() throws BeansException, IllegalStateException {
    
    
		synchronized (this.startupShutdownMonitor) {
    
    
			// Prepare this context for refreshing.
			/**
			 * 前戏,做容器刷新前的准备工作
			 * 1、设置容器的启动时间
			 * 2、设置活跃状态为true
			 * 3、设置关闭状态为false
			 * 4、获取Environment对象,并加载当前系统的属性值到Environment对象中
			 * 5、准备监听器和事件的集合对象,默认为空的集合
			 */

			prepareRefresh();

			// Tell the subclass to refresh the internal bean factory.
			// 创建容器对象:DefaultListableBeanFactory
			// 加载xml配置文件的属性值到当前工厂中,最重要的就是BeanDefinition
			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.
				// 子类覆盖方法做额外的处理,此处我们自己一般不做任何扩展工作,但是可以查看web中的代码,是有具体实现的
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 调用各种beanFactory处理器
				invokeBeanFactoryPostProcessors(beanFactory);
			}		
		}
	}

Insert image description here

@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;
}

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;
}

BFPP and BDRPP

According to the above flow chart and code block, we can see the relationship between BFPP and BDRPP. There is only one postProcessBeanFactory() method in the BFPP class, and there is only the postProcessBeanDefinitionRegistry() method in BDRPP. Because of the inheritance relationship, all classes that implement the BDRPP interface , there will also be a postProcessBeanFactory() method.
A very important difference between BFPP and BDRPP is that the parameters received by their two methods are different. BFPP receives BeanFactory parameters and operates on the entire BeanFactory, while BDRPP receives BeanDefinitionRegistry (which can be understood as doing some operations on Definition). The operation of deleting, modifying and checking) .

BeanDefinitionRegistry

public interface BeanDefinitionRegistry extends AliasRegistry {
    
    

	/**
	 * 注册BeanDefinition到注册表
	 *
	 * Register a new bean definition with this registry.
	 * Must support RootBeanDefinition and ChildBeanDefinition.
	 * @param beanName the name of the bean instance to register
	 * @param beanDefinition definition of the bean instance to register
	 * @throws BeanDefinitionStoreException if the BeanDefinition is invalid
	 * @throws BeanDefinitionOverrideException if there is already a BeanDefinition
	 * for the specified bean name and we are not allowed to override it
	 * @see GenericBeanDefinition
	 * @see RootBeanDefinition
	 * @see ChildBeanDefinition
	 */
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException;

	/**
	 * 移除注册表中beanName的BeanDefinition
	 *
	 * Remove the BeanDefinition for the given name.
	 * @param beanName the name of the bean instance to register
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 */
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * 获取注册表中beanName的BeanDefinition
	 *
	 * Return the BeanDefinition for the given bean name.
	 * @param beanName name of the bean to find a definition for
	 * @return the BeanDefinition for the given name (never {@code null})
	 * @throws NoSuchBeanDefinitionException if there is no such bean definition
	 */
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

	/**
	 * 检查此注册表是否包含具有给定名称的BeanDefinition
	 *
	 * Check if this registry contains a bean definition with the given name.
	 * @param beanName the name of the bean to look for
	 * @return if this registry contains a bean definition with the given name
	 */
	boolean containsBeanDefinition(String beanName);

	/**
	 * 返回此注册表中定义的所有bean的名称
	 *
	 * Return the names of all beans defined in this registry.
	 * @return the names of all beans defined in this registry,
	 * or an empty array if none defined
	 */
	String[] getBeanDefinitionNames();

	/**
	 * 返回注册表中定义的bean的数目
	 *
	 * Return the number of beans defined in the registry.
	 * @return the number of beans defined in the registry
	 */
	int getBeanDefinitionCount();

	/**
	 *  确定给定bean名称是否已在该注册表中使用
	 *
	 * Determine whether the given bean name is already in use within this registry,
	 * i.e. whether there is a local bean or alias registered under this name.
	 * @param beanName the name to check
	 * @return whether the given bean name is already in use
	 */
	boolean isBeanNameInUse(String beanName);

}

The function of the interface and the overall execution process have been introduced. Let's take a look at the specific execution logic of the invokeBeanFactoryPostProcessors method.

invokeBeanFactoryPostProcessors

It mainly calls the invokeBeanFactoryPostProcessors method of the same name in the delegate to process the BFPP implementation classes in BaenFactory and custom registrations.
Among them, getBeanFactoryPostProcessors() means that if the class inherits AbstractApplicationContext, you can have the add method to register BeanFactoryPostProcessor yourself. This part of the BFPP will also be processed first during processing.

invokeBeanFactoryPostProcessors

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
    
    
		// 获取到当前应用程序上下文的beanFactoryPostProcessors变量的值,并且实例化调用执行所有已经注册的beanFactoryPostProcessor
		// 默认情况下,通过getBeanFactoryPostProcessors()来获取已经注册的BFPP,但是默认是空的
		PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

		// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
		if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    
    
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

If you want to register AbstractApplicationContext
yourself, you must implement AbstractApplicationContext and call the addBeanFactoryPostProcessor method to add the custom BFPP implementation class, and you can get it.

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {
    
    
	@Override
	public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) {
    
    
		this.beanFactoryPostProcessors.add(postProcessor);
	}

	/**
	 * Return the list of BeanFactoryPostProcessors that will get applied
	 * to the internal BeanFactory.
	 */
	public List<BeanFactoryPostProcessor> getBeanFactoryPostProcessors() {
    
    
		return this.beanFactoryPostProcessors;
	}
	//删除其他代码
}	

The specific processing logic
is the same as the processing flow marked in the original picture.

  1. All processed BFPPs are put into the processedBeans collection to avoid subsequent repeated execution.
  2. First traverse the BDRPP type in beanFactoryPostProcessors and directly call postProcessBeanDefinitionRegistry for logical processing. Non-BDRPP types are put into the regularPostProcessors collection for subsequent unified processing.
  3. Find the BDRPP type in the BeanFactory, sort it according to PriorityOrdered, Order, and finally execute the ones without priority.
  4. Because those that inherit BDRPP will definitely have methods in BFPP, the postProcessBeanFactory method in BDRPP will also be uniformly processed and executed.
  5. After executing the BDRPP type in the BeanFactory, search for the BFPP type in the BeanFactory, and also prioritize it according to PriorityOrdered and Order. And execute the postProcessBeanFactory method.
class PostProcessorRegistrationDelegate {
    
    

	public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
    
    

		// Invoke BeanDefinitionRegistryPostProcessors first, if any.
        //所有已经执行过BFPP的存储在processedBeans,防止重复执行
		Set<String> processedBeans = new HashSet<String>();
        
        //判断beanFactory是否属于BeanDefinitionRegistry类型,默认的beanFactory是DefaultListableBeanFactory,
        //实现了BeanDefinitionRegistry 所以为true
		if (beanFactory instanceof BeanDefinitionRegistry) {
    
    
            //强制类型转换
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
            
            //存放BFPP类型的集合
			List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>();
            
            //存放BDRPP类型的集合
			List<BeanDefinitionRegistryPostProcessor> registryPostProcessors =
					new LinkedList<BeanDefinitionRegistryPostProcessor>();
            
            //优先处理入参中的beanFactoryPostProcessors,遍历所有beanFactoryPostProcessors,
            //并将参数中的BFPP和BDRPP区分开
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
    
    
                //如果是BDRPP类型
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
    
    
					BeanDefinitionRegistryPostProcessor registryPostProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
                            
                    //直接调用BDRPP中的postProcessBeanDefinitionRegistry具体方法进行处理
					registryPostProcessor.postProcessBeanDefinitionRegistry(registry);
                    //放入registryPostProcessors集合中
					registryPostProcessors.add(registryPostProcessor);
				}
				else {
    
    
                    //否则,只是普通的BeanFactoryPostProcessor,则放入regularPostProcessors集合
					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.
            
            //根据type获取BeanFactory中所有类型为BDRPP的postProcessorNames
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);

			// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
            
            //将实现了BDRPP和priorityOrder接口的类放入该集合
			List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			for (String ppName : postProcessorNames) {
    
    
                //如果是PriorityOrdered类型的
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    
    
                    //放入priorityOrderedPostProcessors集合
					priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    //放入processedBeans集合,避免重复执行
					processedBeans.add(ppName);
				}
			}
            //按照优先级进行排序
			OrderComparator.sort(priorityOrderedPostProcessors);
            //添加到registryPostProcessors中
			registryPostProcessors.addAll(priorityOrderedPostProcessors);
            //遍历priorityOrderedPostProcessors集合,执行postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry);

			// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
            //再次获取BDRPP类型的所有postProcessorNames
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
            //实现了Order接口的BeanDefinitionRegistryPostProcessor放入该集合
			List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>();
			for (String ppName : postProcessorNames) {
    
    
                //如果是没执行过,并且实现了Order接口的
				if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
    
    
                    //放到Order集合中
					orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
                    //放入processedBeans集合,避免重复执行
					processedBeans.add(ppName);
				}
			}
            //按照优先级排序
			OrderComparator.sort(orderedPostProcessors);
            //放入registryPostProcessors集合
			registryPostProcessors.addAll(orderedPostProcessors);
            //遍历orderedPostProcessors集合,执行postProcessBeanDefinitionRegistry方法
			invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry);

			// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
			boolean reiterate = true;
			while (reiterate) {
    
    
				reiterate = false;
                //找出所有实现了BDRPP接口的类
				postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
				for (String ppName : postProcessorNames) {
    
    
                    //跳过执行过BDRPP的类
					if (!processedBeans.contains(ppName)) {
    
    
                        //根据name获取实例
						BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class);
                        //添加到registryPostProcessors集合中
                        registryPostProcessors.add(pp);
                        //添加到processedBeans集合中
						processedBeans.add(ppName);
                        //直接执行BDRPP
						pp.postProcessBeanDefinitionRegistry(registry);
						reiterate = true;
					}
				}
			}   
            
			// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
            //遍历registryPostProcessors和regularPostProcessors中有所的bean,
            //执行BFPP接口postProcessBeanFactory方法
			invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}
        //如果beanFactory不属于BeanDefinitionRegistry,直接执行具体方法
		else {
    
    
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}
        
        //到这为止,入参的beanFactoryPostProcessors和BeanFactory中BDRPP类型的方法已经全部处理完成
        //后面开始都是操作BFPP类型
        //到这位置
		// Do not initialize FactoryBeans here: We need to leave all regular beans
		// uninitialized to let the bean factory post-processors apply to them!
        
        //找到所有实现BeanFactoryPostProcessor的类
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
        //依次声明priorityOrderedPostProcessors、orderedPostProcessorNames和nonOrderedPostProcessorNames分别用来存放对应
        //实现了priorityOrdered、ordered和没实现排序接口的类
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		List<String> orderedPostProcessorNames = new ArrayList<String>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<String>();
        //遍历所有postProcessorNames,将没执行过的BFPP方法的类放入对应集合中。
		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.
        //按照优先级进行排序,并执行具体的BFPP方法
		OrderComparator.sort(priorityOrderedPostProcessors);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

		// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : orderedPostProcessorNames) {
    
    
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		OrderComparator.sort(orderedPostProcessors);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// Finally, invoke all other BeanFactoryPostProcessors.
		List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>();
		for (String postProcessorName : nonOrderedPostProcessorNames) {
    
    
			nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
	}

After reading the above source code, I wonder if anyone has such a question, why is there so much duplicate code? String[] postProcessorNames must be reacquired according to the type every time. After the first acquisition, isn't it possible to prioritize and group execution according to PriorityOrdered and Order based on postProcessorNames?
This is because when executing the BDRPP method postProcessBeanDefinitionRegistry, there may be additional BDRPP classes added, which must be reacquired each time to avoid incomplete execution of the BDRPP classes.

flow chart
Insert image description here

Guess you like

Origin blog.csdn.net/weixin_43936962/article/details/132396273