欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring的BeanFactoryPostProcessor接口示例代碼詳解

 更新時(shí)間:2021年02月24日 14:11:48   作者:程序員自由之路  
這篇文章主要介紹了Spring的BeanFactoryPostProcessor接口,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

接口簡(jiǎn)介

BeanFactoryPostProcessor 接口是 Spring 初始化 BeanFactory 時(shí)對(duì)外暴露的擴(kuò)展點(diǎn),Spring IoC 容器允許 BeanFactoryPostProcessor 在容器實(shí)例化任何 bean 之前讀取 bean 的定義,并可以修改它。

BeanDefinitionRegistryPostProcessor 繼承自 BeanFactoryPostProcessor,比 BeanFactoryPostProcessor 具有更高的優(yōu)先級(jí),主要用來在常規(guī)的 BeanFactoryPostProcessor 檢測(cè)開始之前注冊(cè)其他 bean 定義。特別是,你可以通過 BeanDefinitionRegistryPostProcessor 來注冊(cè)一些常規(guī)的 BeanFactoryPostProcessor,因?yàn)榇藭r(shí)所有常規(guī)的 BeanFactoryPostProcessor 都還沒開始被處理。

注意點(diǎn):通過BeanDefinitionRegistryPostProcessor 注冊(cè)的 BeanDefinitionRegistryPostProcessor 接口的postProcessBeanDefinitionRegistry方法將得不到調(diào)用,具體的原因會(huì)在下面的代碼中解釋。

BeanFactoryPostProcessor 接口調(diào)用機(jī)制

BeanFactoryPostProcessor 接口的調(diào)用在 AbstractApplicationContext#invokeBeanFactoryPostProcessors方法中。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
		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 (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
			beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
			beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
		}
	}

進(jìn)入PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())方法:

public static void invokeBeanFactoryPostProcessors(
			ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
   // 用于存放已經(jīng)處理過的Bean名字
		Set<String> processedBeans = new HashSet<>();
   // 一般會(huì)進(jìn)入這個(gè)判斷
		if (beanFactory instanceof BeanDefinitionRegistry) {
			BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
    // 所謂的regularPostProcessors就是指實(shí)現(xiàn)BeanFactoryPostProcessor接口的Bean
			List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
    // 所謂的registryProcessors就是指實(shí)現(xiàn)BeanDefinitionRegistryPostProcessor接口的Bean
			List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
    // 這邊遍歷的是通過ApplicationContext接口注冊(cè)的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口
    // 需要和BeanFactory中BeanDefinitionMap中的BeanFactoryPostProcessor接口區(qū)分開
			for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
				if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
					BeanDefinitionRegistryPostProcessor registryProcessor =
							(BeanDefinitionRegistryPostProcessor) postProcessor;
      //如果是BeanDefinitionRegistryPostProcessor,則先進(jìn)行postProcessBeanDefinitionRegistry處理,這個(gè)方法一般進(jìn)行BeanDefinition注冊(cè),從這邊可以看出BeanDefinitionRegistryPostProcessor接口的方法先調(diào)用,所以優(yōu)先級(jí)高于BeanFactoryPostProcessor
      // 通過這個(gè)代碼可以看出,通過ApplicationContext直接注冊(cè)的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor并不支持Order接口,而是根據(jù)注冊(cè)的順序執(zhí)行
					registryProcessor.postProcessBeanDefinitionRegistry(registry);
      // 保存這個(gè)BeanDefinitionRegistryPostProcessor,因?yàn)檫€要執(zhí)行這個(gè)類的BeanFactoryPostProcessor方法;
					registryProcessors.add(registryProcessor);
				}
				else {
      // 保存,后面還要執(zhí)行這個(gè)類的BeanFactoryPostProcessor方法;
					regularPostProcessors.add(postProcessor);
				}
			}

			List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
    // 這邊獲取的是BeanFactory中的BeanDefinitionRegistryPostProcessor
			String[] postProcessorNames =
					beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
     //先處理PriorityOrdered標(biāo)注的BeanDefinitionRegistryPostProcessor
				if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
					currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
      //將其標(biāo)記為已經(jīng)處理,防止重復(fù)處理
					processedBeans.add(ppName);
				}
			}
    // 將其排序,以便按順序處理
			sortPostProcessors(currentRegistryProcessors, beanFactory);
    // 將其保存,以便處理這個(gè)類的BeanFactoryPostProcessor方法
			registryProcessors.addAll(currentRegistryProcessors);
    // 執(zhí)行BeanDefinitionRegistryPostProcessor接口方法
			invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
    // 清除,以便開始處理@Order標(biāo)注的注解
			currentRegistryProcessors.clear();
  
    // 注意:這邊重新獲取BeanDefinitionRegistryPostProcessor是有深意的,因?yàn)樯厦嬖谔幚鞞PriorityOrdered標(biāo)注的BeanDefinitionRegistryPostProcessor時(shí)可能又注入了新的BeanDefinitionRegistryPostProcessor。
			postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
			for (String ppName : postProcessorNames) {
     // 判斷是否處理過,防止重復(fù)處理,下面的邏輯和上面相同, 不介紹了
				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();

    // 處理不標(biāo)注注解的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);
				currentRegistryProcessors.clear();
			}

			// 調(diào)用postProcessBeanFactory 方法,所以BeanDefinitionRegistryPostProcessor中的postProcessBeanFactory方法的優(yōu)先級(jí)要高。
			invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
			invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
		}

		else {
			// Invoke factory processors registered with the context instance.
			invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
		}

		// 開始處理BeanFactoryPostProcessor接口
		String[] postProcessorNames =
				beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

		// 也是按照@PriorityOrdered @Ordered 和普通的方式進(jìn)行處理
		List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		List<String> orderedPostProcessorNames = new ArrayList<>();
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		for (String ppName : postProcessorNames) {
    // 可能已經(jīng)處理過
			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);
			}
		}
   // 先執(zhí)行@PriorityOrdered標(biāo)注的接口
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
   // 處理@Order標(biāo)注的類
		List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		for (String postProcessorName : orderedPostProcessorNames) {
    // 這邊通過名字重新拿了Bean,應(yīng)該是怕上面的處理改變了Bean
			orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
		}
		sortPostProcessors(orderedPostProcessors, beanFactory);
		invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

		// 最后調(diào)用普通的BeanFactoryPostProcessor
		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();
	}

簡(jiǎn)單總結(jié)

上面的方法看起來很長(zhǎng)很復(fù)雜,但其實(shí)干的事情并不多,就調(diào)用了BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口的實(shí)現(xiàn)。這邊再簡(jiǎn)單總結(jié)下具體的過程:

step1:執(zhí)行通過ApplicationContext#addBeanFactoryPostProcessor()方法注冊(cè)的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor。

具體過程如下:假如通過ApplicationContext注冊(cè)了一個(gè)BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor,那么會(huì)先執(zhí)行BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,但是BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法和BeanFactoryPostProcessor的postProcessBeanFactory方法暫時(shí)都不會(huì)在這步執(zhí)行。

另外需要注意的是:通過ApplicationContext注冊(cè)的BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor都不支持@PriorityOrdered和@Ordered順序處理,而是按照我們添加的順序處理

step2:處理BeanFactory中的BeanDefinitionRegistryPostProcessor,處理的順序是先處理@PriorityOrdered標(biāo)注的,再處理@Ordered標(biāo)注的,最后處理普通的BeanDefinitionRegistryPostProcessor。到這邊,所有BeanDefinitionRegistryPostProcessor接口的postProcessBeanDefinitionRegistry方法都已經(jīng)調(diào)用完畢,下面就開始處理BeanFactoryPostProcessor的postProcessBeanFactory方法。

step3:調(diào)用BeanDefinitionRegistryPostProcessor實(shí)現(xiàn)的postProcessBeanFactory方法(因?yàn)锽eanDefinitionRegistryPostProcessor是BeanFactoryPostProcessor的子接口)

step4:調(diào)用通過ApplicationContext#addBeanFactoryPostProcessor()注冊(cè)的“單純”的BeanFactoryPostProcessor

step5:調(diào)用BeanFactory中的BeanFactoryPostProcessor,調(diào)用順序也是按照@PriorityOrdered和@Ordered順序處理,沒有這兩個(gè)注解的最后處理。

好了,到這邊BeanFactoryPostProcessor和BeanDefinitionRegistryPostProcessor接口就已經(jīng)處理完了。后面我們會(huì)拿ConfigurationClassPostProcessor 這個(gè)特殊的BeanDefinitionRegistryPostProcessor做列子講下具體流程,這邊只是介紹BeanFactoryPostProcessor的調(diào)用機(jī)制。

到此這篇關(guān)于Spring的BeanFactoryPostProcessor接口的文章就介紹到這了,更多相關(guān)Spring BeanFactoryPostProcessor接口內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java累加和校驗(yàn)實(shí)現(xiàn)方式16進(jìn)制(推薦)

    java累加和校驗(yàn)實(shí)現(xiàn)方式16進(jìn)制(推薦)

    下面小編就為大家?guī)硪黄猨ava累加和校驗(yàn)實(shí)現(xiàn)方式16進(jìn)制(推薦)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2016-11-11
  • SpringMVC異常處理的三種方式

    SpringMVC異常處理的三種方式

    在SpringMVC中異常處理是一個(gè)重要的方面,它幫助我們有效地處理應(yīng)用程序中的異常情況,提高用戶體驗(yàn)和系統(tǒng)的穩(wěn)定性,這篇文章主要給大家介紹了關(guān)于SpringMVC異常處理的三種方式,需要的朋友可以參考下
    2024-02-02
  • Spring注解驅(qū)動(dòng)之BeanFactoryPostProcessor原理解析

    Spring注解驅(qū)動(dòng)之BeanFactoryPostProcessor原理解析

    這篇文章主要介紹了Spring注解驅(qū)動(dòng)之BeanFactoryPostProcessor原理,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-09-09
  • SpringBoot整合RabbitMQ實(shí)現(xiàn)消息確認(rèn)機(jī)制

    SpringBoot整合RabbitMQ實(shí)現(xiàn)消息確認(rèn)機(jī)制

    這篇文章主要介紹了SpringBoot整合RabbitMQ實(shí)現(xiàn)消息確認(rèn)機(jī)制,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • Java基礎(chǔ)知識(shí)之CharArrayWriter流的使用

    Java基礎(chǔ)知識(shí)之CharArrayWriter流的使用

    這篇文章主要介紹了Java基礎(chǔ)知識(shí)之CharArrayWriter流的使用,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • Java中防止數(shù)據(jù)重復(fù)提交超簡(jiǎn)單的6種方法

    Java中防止數(shù)據(jù)重復(fù)提交超簡(jiǎn)單的6種方法

    在平時(shí)開發(fā)中,如果網(wǎng)速比較慢的情況下,用戶提交表單后,發(fā)現(xiàn)服務(wù)器半天都沒有響應(yīng),那么用戶可能會(huì)以為是自己沒有提交表單,就會(huì)再點(diǎn)擊提交按鈕重復(fù)提交表單,這篇文章主要給大家介紹了關(guān)于Java中防止數(shù)據(jù)重復(fù)提交超簡(jiǎn)單的6種方法,需要的朋友可以參考下
    2021-11-11
  • java實(shí)現(xiàn)菜單滑動(dòng)效果

    java實(shí)現(xiàn)菜單滑動(dòng)效果

    這篇文章主要介紹了java實(shí)現(xiàn)菜單滑動(dòng)效果,效果非常棒,這里推薦給大家,有需要的小伙伴可以參考下。
    2015-03-03
  • Java中的@RequiredArgsConstructor注解詳解

    Java中的@RequiredArgsConstructor注解詳解

    這篇文章主要介紹了Java中的@RequiredArgsConstructor注解詳解,@RequiredArgsConstructor是Lombok的一個(gè)注解,簡(jiǎn)化了我們對(duì)@Autowired書寫,@RequiredArgsConstructor注解可以代替@Autowired注解,需要的朋友可以參考下
    2024-01-01
  • Java使用自動(dòng)化部署工具Gradle中的任務(wù)設(shè)定教程

    Java使用自動(dòng)化部署工具Gradle中的任務(wù)設(shè)定教程

    Grandle使用同樣運(yùn)行于JVM上的Groovy語言編寫,本文會(huì)對(duì)此進(jìn)行初步夠用的講解,接下來我們就一起來看一下Java使用自動(dòng)化部署工具Gradle中的任務(wù)設(shè)定教程:
    2016-06-06
  • 如何用java編寫微信小程序消息提醒推送

    如何用java編寫微信小程序消息提醒推送

    最近參與開發(fā)的項(xiàng)目有用到微信模板消息推送,在這離記錄一下,下面這篇文章主要給大家介紹了關(guān)于如何用java編寫微信小程序消息提醒推送的相關(guān)資料,需要的朋友可以參考下
    2023-11-11

最新評(píng)論