最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Spring中幾個PostProcessor的區(qū)別與聯(lián)系

 更新時間:2021年08月13日 10:55:09   作者:碩子鴿  
這篇文章主要介紹了淺談Spring中幾個PostProcessor的區(qū)別與聯(lián)系,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教

Spring幾個PostProcessor的區(qū)別

首先明確 Bean 的生命周期:

  • 首先注冊 Bean 的定義信息;
  • 然后創(chuàng)建 Bean 的實例;
  • 最后初始化 Bean ,放入容器中。

按照執(zhí)行的順序,可以分為以下幾個步驟:

BeanDefinitionRegistryPostProcessor 是在注冊 Bean 定義信息前后調(diào)用;

BeanFactoryPostProcessor 是在創(chuàng)建 Bean 前后調(diào)用;

BeanPostProcessor 是在初始化 Bean 前后調(diào)用;

其中 BeanDefinitionRegistryPostProcessor 是 BeanFactoryPostProcessor 的子類,所以可以使用前者代替后者實現(xiàn)功能。

查看 IOC 容器創(chuàng)建時的調(diào)用流程

refresh 方法的代碼如下:

// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
finishRefresh();

其中的 invokeBeanFactoryPostProcessors 就執(zhí)行了注冊定義信息和創(chuàng)建 Bean 的方法;而 finishBeanFactoryInitialization 執(zhí)行了初始化 Bean 的方法。

具體的執(zhí)行順序大家可以自行打斷點調(diào)試,由于涉及的源碼過多,這里不再展示。

spring-postProcessor的執(zhí)行時機(jī)

spring bean 的生命周期粗糙的分為以下步驟。

實例化(創(chuàng)建一個屬性都為空的對象)---------》屬性填充(populateBean,下文中這個步驟我都稱為初始化)-----------》init方法的執(zhí)行(invokerInitMethods,下文稱為init)

postprocessor的方法就是穿插在這三個大的步驟中。

BeanPostProcessor:

postProcessBeforeInitialization調(diào)用時機(jī)

向上找調(diào)用者:

繼續(xù)向上:

看以看出populateBean(初始化bean)-------------------》beanpostBeforeInitialization---------------------------------->invokeinitMethods(配置的init-method)

postProcessAfterInitialization調(diào)用時機(jī):

向上:

可以看出在init-method方法之后

看以看出populateBean(初始化bean)-------------------》beanpostBeforeInitialization---------------------------------->invokeinitMethods(配置的init-method)------->postProcessAfterInitialization

public class MBeanPostProcessor implements BeanPostProcessor { 
    @Override
    //populateBean之后   invokeinitMethods之前
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("post bean before! :"+beanName);
        return bean;
    }
 
    @Override
    //invokeinitMethods之后
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("post bean after!"+beanName);
        return bean;
    }
}

另一個重要的是:

InstantiationAwareBeanPostProcessor

postProcessBeforeInstantiation調(diào)用時機(jī):

向上找調(diào)用者:

繼續(xù)向上:

可以看出是在實例化之前:(也就是反射創(chuàng)建對象之前,如果postProcessBeforeInstantiation創(chuàng)建了一個非空的對象,則不會走實例化步驟。

postProcessAfterInstantiation調(diào)用時機(jī):

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   PropertyValues pvs = mbd.getPropertyValues();
 
   if (bw == null) {
      if (!pvs.isEmpty()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         // Skip property population phase for null instance.
         return;
      }
   }
 
   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
   // state of the bean before properties are set. This can be used, for example,
   // to support styles of field injection.
   boolean continueWithPropertyPopulation = true;
 
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            //在這里執(zhí)行
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               continueWithPropertyPopulation = false;
               break;
            }
         }
      }
   }
 
   if (!continueWithPropertyPopulation) {
      return;
   }
 省略。。。。。 
   applyPropertyValues(beanName, mbd, bw, pvs);
}

可以看出是在在初始化之前,具體是屬性填充之前。(初始化之前,實例化之后) 如果返回fales,則不會繼續(xù)初始化,即不會屬性填充。

postProcessPropertyValues調(diào)用時機(jī):

protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
   PropertyValues pvs = mbd.getPropertyValues(); 
   if (bw == null) {
      if (!pvs.isEmpty()) {
         throw new BeanCreationException(
               mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
      }
      else {
         // Skip property population phase for null instance.
         return;
      }
   }
 
   // Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
   // state of the bean before properties are set. This can be used, for example,
   // to support styles of field injection.
   boolean continueWithPropertyPopulation = true;
 
   if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
      for (BeanPostProcessor bp : getBeanPostProcessors()) {
         if (bp instanceof InstantiationAwareBeanPostProcessor) {
            InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
            if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
               continueWithPropertyPopulation = false;
               break;
            }
         }
      }
   }
 
   if (!continueWithPropertyPopulation) {
      return;
   }
 
   if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME ||
         mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
      MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
 
      // Add property values based on autowire by name if applicable.
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_NAME) {
         autowireByName(beanName, mbd, bw, newPvs);
      }
 
      // Add property values based on autowire by type if applicable.
      if (mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_BY_TYPE) {
         autowireByType(beanName, mbd, bw, newPvs);
      } 
      pvs = newPvs;
   }
 
   boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
   boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
 
   if (hasInstAwareBpps || needsDepCheck) {
      PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
      if (hasInstAwareBpps) {
         for (BeanPostProcessor bp : getBeanPostProcessors()) {
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
               InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
               pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
               if (pvs == null) {
                  return;
               }
            }
         }
      }
      if (needsDepCheck) {
         checkDependencies(beanName, mbd, filteredPds, pvs);
      }
   } 
   applyPropertyValues(beanName, mbd, bw, pvs);
}

在postProcessAfterInstantiation之后,applyPropertyValues之前。(屬性填充之前修改屬性值)

總結(jié): 執(zhí)行順序

  • 1.postProcessBeforeInstantiation(實現(xiàn)這個方法可以做自定義實例化)
  • 2.實例化
  • 3.postProcessAfterInstantiation(是否要初始化)
  • 4.postProcessPropertyValues(修改屬性)
  • 5.初始化(屬性填充)(populateBean)
  • 6.postProcesstBeforeInitialization( 自定義init方法執(zhí)行之前)
  • 7.invokeinitMethods(執(zhí)行自定義的init方法)
  • 8.postProcessAfterInitialization(自定義init方法執(zhí)行之后)

如果加上aware

  • 1.postProcessBeforeInstantiation(實現(xiàn)這個方法可以做自定義實例化)
  • 2.實例化
  • 3.postProcessAfterInstantiation(是否要初始化)
  • 4.postProcessPropertyValues(修改屬性)
  • 5.初始化(屬性填充)(populateBean)
  • 6.postProcesstBeforeInitialization( 自定義init方法執(zhí)行之前)
  • 7.invokeAwareMethod
  • 8.invokeinitMethods(執(zhí)行自定義的init方法)
  • 9.postProcessAfterInitialization(自定義init方法執(zhí)行之后)

以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • Java8新特性之默認(rèn)方法詳解

    Java8新特性之默認(rèn)方法詳解

    JAVA8 所提供的默認(rèn)方法,就是在接口上你可以定義某些方法的實現(xiàn),下面這篇文章主要給大家介紹了關(guān)于Java8新特性之默認(rèn)方法的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-02-02
  • SpringMVC ViewResolver視圖解析器組件

    SpringMVC ViewResolver視圖解析器組件

    這篇文章主要介紹了SpringMVC ViewResolver視圖解析器組件,Spring MVC的視圖解析器 ViewResolver 是框架中一個重要的組件,用于將控制器返回的邏輯視圖名稱解析為具體的視圖實現(xiàn)對象,最終呈現(xiàn)給用戶的是具體的視圖實現(xiàn)
    2023-04-04
  • Java開發(fā)中POJO和JSON互轉(zhuǎn)時如何忽略隱藏字段的問題

    Java開發(fā)中POJO和JSON互轉(zhuǎn)時如何忽略隱藏字段的問題

    這篇文章主要介紹了Java開發(fā)中POJO和JSON互轉(zhuǎn)時如何忽略隱藏字段的問題,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-02-02
  • SpringBoot3+graalvm:整合并打包為可執(zhí)行文件方式

    SpringBoot3+graalvm:整合并打包為可執(zhí)行文件方式

    本文介紹了如何在Spring Boot 3中整合GraalVM,并將其打包為可執(zhí)行文件,適用于Windows和Linux系統(tǒng),通過安裝GraalVM、配置環(huán)境變量、下載Visual Studio組件(僅限Windows)以及使用Maven容器(適用于Linux),可以實現(xiàn)高效的打包和運(yùn)行
    2024-12-12
  • 詳解java.lang.NumberFormatException錯誤及解決辦法

    詳解java.lang.NumberFormatException錯誤及解決辦法

    這篇文章主要介紹了詳解java.lang.NumberFormatException錯誤及解決辦法,本文詳解的介紹了錯誤的解決方法,感興趣的可以一起來了解一下
    2020-05-05
  • 淺談cookie 和session 的區(qū)別

    淺談cookie 和session 的區(qū)別

    下面小編就為大家?guī)硪黄獪\談cookie 和session 的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-06-06
  • Spring boot整合security詳解

    Spring boot整合security詳解

    Spring Security是一個功能強(qiáng)大且高度可定制的身份驗證和訪問控制框架,本文主要介紹了SpringBoot整合Security安全框架的方法,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-07-07
  • Kotlin 基本語法實例詳解

    Kotlin 基本語法實例詳解

    這篇文章主要介紹了Kotlin 基本語法實例詳解的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • Java圖像處理之RGB調(diào)色面板

    Java圖像處理之RGB調(diào)色面板

    這篇文章主要為大家詳細(xì)介紹了Java圖像處理之RGB調(diào)色面板,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-06-06
  • Java利用Easyexcel導(dǎo)出excel表格的示例代碼

    Java利用Easyexcel導(dǎo)出excel表格的示例代碼

    這篇文章主要為大家詳細(xì)介紹了Java利用Easyexcel導(dǎo)出excel表格的示例代碼,文中的代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起了解一下
    2022-07-07

最新評論

高青县| 梓潼县| 江阴市| 莎车县| 土默特右旗| 庐江县| 黔西县| 温泉县| 普兰县| 日喀则市| 梁平县| 九龙坡区| 桂平市| 大方县| 文登市| 桦川县| 泸溪县| 垦利县| 木里| 仲巴县| 瓮安县| 尚志市| 朔州市| 渭南市| 洪湖市| 五大连池市| 东源县| 五常市| 太康县| 靖宇县| 金堂县| 天全县| 桂东县| 民和| 县级市| 岳阳市| 沽源县| 新宁县| 阆中市| 靖州| 焦作市|