亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

關(guān)于Spring BeanPostProcessor的執(zhí)行順序

 更新時(shí)間:2021年10月14日 08:37:52   作者:碩子鴿  
這篇文章主要介紹了Spring BeanPostProcessor的執(zhí)行順序,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

Spring BeanPostProcessor執(zhí)行順序

首先 Spring 通過調(diào)用構(gòu)造方法創(chuàng)建 User 對象;

User 對象創(chuàng)建好之后,先不直接進(jìn)行初始化操作,通過 BeanPostProcessor 對剛創(chuàng)建好的 User 對象進(jìn)行加工操作,其中 postProcessBeforeInitialization 方法的第一個(gè)參數(shù)是 User 對象,第二個(gè)參數(shù)是在配置文件中指定的 id 值;

加工好之后通過 return 將對象返回給 Spring 容器,然后 Spring 容器繼續(xù)按照流程執(zhí)行 初始化操作,先是 InitializingBean 的初始化操作;

再是 init-method 的初始化;

然后 Spring 容器再次將對象交給 BeanPostProcessor ,執(zhí)行 postProcessAfterInitialization 方法。

實(shí)際上在實(shí)戰(zhàn)中,我們很少處理 Spring 的初始化操作,所以沒有必要區(qū)分 Before 還是 After。只需要實(shí)現(xiàn)其中的一個(gè)即可,顯然選 After 方法更好。

先定義一個(gè)實(shí)體類 Category:

public class Category {
  private Integer id;
  private String name;
  public Integer getId() {
      return id;
  }
  public void setId(Integer id) {
      this.id = id;
  }
  public String getName() {
      return name;
  }
  public void setName(String name) {
      this.name = name;
  }
  @Override
  public String toString() {
      return "Category{" +
              "id=" + id +
              ", name='" + name + '\'' +
              '}';
  }
}

然后注入到 Spring 容器中:

<bean class="edu.lsu.pojo.Category" id="category">
  <property name="id" value="1"/>
  <property name="name" value="迪麗熱巴"/>
</bean>

注意此時(shí)的名字是迪麗熱巴。

此時(shí)我們定義一個(gè) BeanPostProcessor,實(shí)現(xiàn)他的后置處理器方法:

public class MyBeanPostProcessor implements BeanPostProcessor {
  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
      return bean;
  }
  @Override
  public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      Category category = (Category) bean;
      category.setName("古力娜扎");
      return category;
  }
}

當(dāng)我們在此時(shí)的時(shí)候,輸出結(jié)果就是古力娜扎;

@Test
public void test7() {
  ApplicationContext ac = new ClassPathXmlApplicationContext("/applicationContext2.xml");
  Category category = ac.getBean("category", Category.class);
  System.out.println("category = " + category);
}

輸出:

category = Category{id=1, name='古力娜扎'}

Spring-BeanPostProcessor接口總結(jié)

定義

Spring提供了一個(gè)BeanPostProcessor接口,這個(gè)接口的作用在于對于新構(gòu)造的實(shí)例可以做一些自定義的修改。比如如何構(gòu)造、屬性值的修改、構(gòu)造器的選擇。

如果想改變Spring容器中bean的一些屬性或者行為,可以通過自定義類實(shí)現(xiàn)BeanPostProcessor接口實(shí)現(xiàn)。

以下基本Spring-beans 5.0.6版本說明。

BeanPostProcessor

@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
 return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
 return bean;
}

BeanPostProcessor總結(jié)

  • postProcessBeforeInitialization方法的作用在于目標(biāo)對象實(shí)例化之后,初始化之前調(diào)用,默認(rèn)返回原始對象,也可以返回一個(gè)包裝實(shí)例;
  • 如果返回null,接下來的BeanPostProcessors都不會(huì)執(zhí)行
  • postProcessAfterInitialization方法的作用在于目標(biāo)對象實(shí)例化之后,初始化之后調(diào)用,默認(rèn)返回原始對象,也可以返回一個(gè)包裝實(shí)例;
  • 如果返回null,接下來的BeanPostProcessors都不會(huì)執(zhí)行
  • 初始化(Initialization):表示生成對象,未設(shè)置屬性;初始化之前表示bean的初始化回調(diào)之前,如InitializingBean接口的afterPropertiesSet方法或者自定義的init-method方法

InstantiationAwareBeanPostProcessor

InstantiationAwareBeanPostProcessor接口繼承自BeanPostProcessor接口,定義了3個(gè)方法

@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
 return null;
}
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
 return true;
}
@Nullable
default PropertyValues postProcessPropertyValues(
  PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
 return pvs;
}

InstantiationAwareBeanPostProcessor總結(jié)

  • postProcessBeforeInstantiation方法在目標(biāo)對象實(shí)例化之前調(diào)用,可以返回一個(gè)代理對象來代替目標(biāo)對象本身;如果返回非null對象,則除了調(diào)用postProcessAfterInitialization方法外,其他bean的構(gòu)造過程都不再調(diào)用;
  • postProcessAfterInstantiation方法在對象實(shí)例化之后,屬性設(shè)置之前調(diào)用;如果返回值是true,目標(biāo)bean的屬性會(huì)被populate,返回false則忽略populate過程;
  • postProcessPropertyValues方法在屬性被設(shè)置到目標(biāo)實(shí)例之前調(diào)用,可以修改屬性的設(shè)置,PropertyValues pvs表示參數(shù)值,PropertyDescriptor[] pds表示目標(biāo)bean 的屬性描述信息,返回值PropertyValues,可以用一個(gè)全新的PropertyValues來替代原來的pvs,如果返回null,將忽略屬性設(shè)置過程;

SmartInstantiationAwareBeanPostProcessor

SmartInstantiationAwareBeanPostProcessor接口繼承InstantiationAwareBeanPostProcessor接口,定義了3個(gè)方法,作用是在于目標(biāo)對象的實(shí)例化過程中需要處理的事情。

@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
 return null;
}
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
  throws BeansException {
 return null;
}
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
 return bean;
}

SmartInstantiationAwareBeanPostProcessor總結(jié)

  • predictBeanType方法預(yù)測Bean的類型,返回預(yù)測成功的Class類型,默認(rèn)或如果不能預(yù)測返回null
  • determineCandidateConstructors方法用于選擇合適的構(gòu)造器,如果類有多個(gè)構(gòu)造器,可以實(shí)現(xiàn)這個(gè)方法選擇合適的構(gòu)造器并用于實(shí)例化對象;該方法在postProcessBeforeInstantiation方法和postProcessAfterInstantiation方法之間調(diào)用,如果postProcessBeforeInstantiation方法返回了一個(gè)新的實(shí)例代替了原本該生成的實(shí)例,那么該方法會(huì)被忽略;
  • getEarlyBeanReference方法用于解決循環(huán)引用問題。比如ReferenceA實(shí)例內(nèi)部有ReferenceB的引用,ReferenceB實(shí)例內(nèi)部有ReferenceA的引用。首先先實(shí)例化ReferenceA,實(shí)例化完成之后提前把這個(gè)bean暴露在ObjectFactory中,然后populate屬性,這個(gè)時(shí)候發(fā)現(xiàn)需要ReferenceB。然后去實(shí)例化ReferenceB,在實(shí)例化ReferenceB的時(shí)候它需要ReferenceA的實(shí)例才能繼續(xù),這個(gè)時(shí)候就會(huì)去ObjectFactory中找出了ReferenceA實(shí)例,ReferenceB順利實(shí)例化。ReferenceB實(shí)例化之后,ReferenceA的populate屬性過程也成功完成,注入了ReferenceB實(shí)例。提前把這個(gè)bean暴露在ObjectFactory中,這個(gè)ObjectFactory獲取的實(shí)例就是通過getEarlyBeanReference方法得到的;

DestructionAwareBeanPostProcessor

void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
default boolean requiresDestruction(Object bean) {
 return true;
}

DestructionAwareBeanPostProcessor總結(jié)

postProcessBeforeDestruction方法在目標(biāo)bean被銷毀之前調(diào)用,該回調(diào)適用于單例bean的使用;

判斷目標(biāo)bean是否需要回調(diào)postProcessBeforeDestruction方法;

總結(jié)一下

Spring內(nèi)部對象bean的生命周期管理有一套完成的體系,并遵循了設(shè)計(jì)模式中的開閉原則(開放擴(kuò)展,關(guān)閉修改),如果想修改bean的相關(guān)信息,可以通過Spring提供的擴(kuò)展點(diǎn),如BeanPostProcessor接口去處理,這樣做的好處是不需要關(guān)心Spring內(nèi)部處理邏輯,擴(kuò)展方便。

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

相關(guān)文章

  • 在Eclipse安裝Spring boot插件的步驟(圖文)

    在Eclipse安裝Spring boot插件的步驟(圖文)

    這篇文章主要介紹了在Eclipse安裝Spring boot插件的步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-08-08
  • Java實(shí)現(xiàn)QQ第三方登錄的示例代碼

    Java實(shí)現(xiàn)QQ第三方登錄的示例代碼

    這篇文章主要介紹了Java實(shí)現(xiàn)QQ第三方登錄的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • java使用dom4j操作xml示例代碼

    java使用dom4j操作xml示例代碼

    dom4j是一個(gè)Java的XML API,類似于jdom,用來讀寫XML文件,下面我來個(gè)小例子學(xué)習(xí)他的使用方法
    2013-11-11
  • RocketMQ的push消費(fèi)方式實(shí)現(xiàn)示例

    RocketMQ的push消費(fèi)方式實(shí)現(xiàn)示例

    這篇文章主要為大家介紹了RocketMQ的push消費(fèi)方式實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪<BR>
    2022-08-08
  • servlet監(jiān)聽實(shí)現(xiàn)統(tǒng)計(jì)在線人數(shù)功能 附源碼下載

    servlet監(jiān)聽實(shí)現(xiàn)統(tǒng)計(jì)在線人數(shù)功能 附源碼下載

    這篇文章主要為大家詳細(xì)介紹了servlet監(jiān)聽統(tǒng)計(jì)在線人數(shù)的實(shí)現(xiàn)方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • 深入介紹Spring框架及故障排除

    深入介紹Spring框架及故障排除

    這篇文章主要介紹了深入介紹Spring框架及故障排除,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的小伙伴可以參考一下
    2022-06-06
  • 后端java壓縮圖片超詳細(xì)圖文教程

    后端java壓縮圖片超詳細(xì)圖文教程

    這篇文章主要給大家介紹了關(guān)于后端java壓縮圖片的相關(guān)資料,片壓縮是一種廣泛采用的技術(shù),它不僅能顯著減小文件大小,釋放更多存儲(chǔ)空間,還能提升圖片加載速度,避免長時(shí)間等待,需要的朋友可以參考下
    2024-04-04
  • Java獲取網(wǎng)絡(luò)文件并插入數(shù)據(jù)庫的代碼

    Java獲取網(wǎng)絡(luò)文件并插入數(shù)據(jù)庫的代碼

    抓取各大網(wǎng)站的數(shù)據(jù)插入數(shù)據(jù)庫,這樣就不用為沒有數(shù)據(jù)而煩惱了
    2010-06-06
  • Java基于命令模式實(shí)現(xiàn)郵局發(fā)信功能詳解

    Java基于命令模式實(shí)現(xiàn)郵局發(fā)信功能詳解

    這篇文章主要介紹了Java基于命令模式實(shí)現(xiàn)郵局發(fā)信功能,較為詳細(xì)的分析了命令行模式的概念、原理并結(jié)合實(shí)例形式分析了Java使用命令行模式實(shí)現(xiàn)郵局發(fā)信功能的相關(guān)操作技巧與注意事項(xiàng),需要的朋友可以參考下
    2018-04-04
  • ByteArrayOutputStream簡介和使用_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    ByteArrayOutputStream簡介和使用_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    ByteArrayOutputStream 是字節(jié)數(shù)組輸出流。它繼承于OutputStream。這篇文章主要介紹了ByteArrayOutputStream簡介和使用,需要的朋友可以參考下
    2017-05-05

最新評(píng)論