Spring ソース コード (7) - ポストプロセッサ

前回の記事を簡単に復習すると、BeanFacroty の作成後、Editor と EditorRegistrar を使用してクラス属性にカスタム拡張を実装し、自動的にアセンブルされる Aware インターフェースを無視できることがわかります。
この投稿では、refresh() メイン プロセス メソッドに従い、下方向に実行します。invokeBeanFactoryPostProcessors メソッドの具体的なロジックについて説明する前に、BeanFactoryPostProcessor インターフェースと invokeBeanFactoryPostProcessors メソッド全体の実行プロセスについて簡単に紹介します。

リフレッシュする

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

ここに画像の説明を挿入

@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 と BDRPP

上記のフローチャートとコードブロックによると、BFPP と BDRPP の関係がわかります。BFPP クラスには postProcessBeanFactory() メソッドが 1 つだけあり、BDRPP には postProcessBeanDefinitionRegistry() メソッドしかありません。 BDRPP インターフェースを実装するすべてのクラスには、postProcessBeanFactory() メソッドもあります。
BFPP と BDRPP の非常に重要な違いは、これら 2 つのメソッドで受信されるパラメータが異なることです。BFPP はBeanFactory パラメータを受信し、BeanFactory 全体で操作しますが、BDRPP は BeanDefinitionRegistry を受信します (定義に対して何らかの操作を実行すると理解できます)。削除、変更、確認)

Bean定義レジストリ

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

}

インターフェースの機能と実行プロセス全体を紹介しましたが、次に invokeBeanFactoryPostProcessors メソッドの具体的な実行ロジックを見てみましょう。

invokeBeanFactoryPostProcessors

主にデリゲート内で同名の invokeBeanFactoryPostProcessors メソッドを呼び出して、BaenFactory に登録された BFPP 実装クラスとカスタム登録を処理します。
このうち getBeanFactoryPostProcessors() は、クラスが AbstractApplicationContext を継承する場合、BeanFactoryPostProcessor を独自に登録する add メソッドがあることを意味します。BFPP のこの部分も最初に処理されます。

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

AbstractApplicationContext
を自分で登録したい場合は、AbstractApplicationContext を実装し、addBeanFactoryPostProcessor メソッドを呼び出してカスタム BFPP 実装クラスを追加することで取得できます。

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;
	}
	//删除其他代码
}	

具体的な処理ロジックは
最初の図に記載した処理フローと同じですが、

  1. 処理された BFPP は、後続の繰り返し実行を避けるために、processedBeans コレクションに入れられます。
  2. まず、beanFactoryPostProcessors の BDRPP タイプを走査し、ロジック処理のために postProcessBeanDefinitionRegistry を直接呼び出します。非 BDRPP タイプは、後続の統合処理のために RegularPostProcessors コレクションに配置されます。
  3. BeanFactory で BDRPP タイプを検索し、PriorityOrdered、Order に従って優先順位のソートを実行し、最後に優先順位のないものを実行します。
  4. BDRPPを継承する人は必ずBFPPのメソッドを持つことになるので、BDRPPのpostProcessBeanFactoryメソッドも統一的に処理・実行されることになります。
  5. BeanFactory で BDRPP タイプを実行した後、BeanFactory で BFPP タイプを検索し、PriorityOrdered と Order に従って優先順位のソートも実行します。そして、postProcessBeanFactoryメソッドを実行します。
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);
	}

上記のソースコードを読んで、なぜ重複したコードがたくさんあるのですか? その都度 String[] postProcessorNames を型に応じて再取得する必要があり、初回取得後は PriorityOrdered と Order に従って postProcessorNames に優先順位が付けられ、グループ実行では足りないのでは?
これは、BDRPP の postProcessBeanDefinitionRegistry メソッドを実行するときに、新たに追加された BDRPP クラスが存在する可能性があり、そのたびに再取得できるため、BDRPP クラスの不完全な実行を回避できます。

フローチャート
ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_43936962/article/details/132396273