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

深入解析Spring Bean初始化時和銷毀時的擴展點

 更新時間:2023年08月04日 09:35:11   作者:劉牌  
在Bean進行初始化或者銷毀的時候,如果我們需要做一些操作,比如加載和銷毀一些資源或者執(zhí)行一些方法時,那么就可以使用Spring提供的一些擴展,今天主要分享初始化Bean時的三種方式和銷毀Bean時的三種方式,需要的朋友可以參考下

一.前言

今天來分享一下Bean在初始化時和Bean銷毀時我們可以做的一些操作,如果只是單純做CRUD開發(fā),那么這些操作基本上不可能遇到,如果依賴于Spring來做一些框架層面的開發(fā)或者中間件開發(fā),那么這些操作是很常用的,在Bean進行初始化或者銷毀的時候,如果我們需要做一些操作,比如加載和銷毀一些資源或者執(zhí)行一些方法時,那么就可以使用Spring提供的一些擴展,今天主要分享初始化Bean時的三種方式和銷毀Bean時的三種方式。

二.相關(guān)擴展點和方法

初始化時和銷毀時都有相應(yīng)的方式供我們選擇,下面列出了初始化時和銷毀時的各三種方式,然后再進行深度解析。

初始化時

  • @PostConstruct
  • 自定義初始化方法
  • InitializingBean

銷毀時

  • @PreDestroy
  • 自定義銷毀方法
  • DisposableBean

三.測試

定義Bean

下面我們定義了一個Bean,實現(xiàn)了InitializingBean和DisposableBean接口,分別在方法上使用了@PostConstruct注解和@PreDestroy注解,又自定義了初始化方法initMethod()和銷毀方法destoryMethod()。

配置Bean

使用@Configuration注解和@Bean注解來注冊Bean,我們在InitDestroyBean上使用了@Bean注解來將其標(biāo)注為一個Bean,并且加上了初始化方法和銷毀方法。

查看結(jié)果

從控制臺輸出我們可以得出這些方式的優(yōu)先級

  • @PostConstruct > InitializingBean > 自定義初始化方法

  • @PreDestroy > DisposableBean > 自定義銷毀方法

四.源碼解析

下面進行源碼解析,因為Spring的源碼還是比較復(fù)雜,所以我們只從最關(guān)鍵的地方開始分析,下分析初始化Bean時,再分析銷毀Bean時。

初始化Bean

1.解析Bean中@PostConstruct注解和@PreDestory注解

我們直接來到AbstractAutowireCapableBeanFactory類中,@PostConstruct注解和@PreDestory標(biāo)注的方法會在applyMergedBeanDefinitionPostProcessors中被后置處理器InitDestroyAnnotationBeanPostProcessor解析,原理是通過反射判斷Bean中是否有方法上標(biāo)注了@PostConstruct注解和@PreDestory注解,如果有,則將其加入initMethodsdestroyMethods集合中,然后組裝到LifecycleMetadata中,以供后續(xù)使用。

2.對Bean進行初始化-調(diào)用標(biāo)注@PostConstruct的方法

下一步進入initializeBean方法中,然后進入applyBeanPostProcessorsBeforeInitialization方法,從名字我們可以看出這是Bean初始化前操作,這里會調(diào)用InitDestroyAnnotationBeanPostProcessor后置處理進行處理。

從上面可以看出會通過findLifecycleMetadata去獲取元數(shù)據(jù),就是上面我們說的LifecycleMetadata,這里會用到,然后調(diào)用invokeInitMethods方法,最終會通過反射調(diào)用到標(biāo)注了@PostConstruct注解的方法。

從上面我們可以看出,標(biāo)注了@PostConstruct注解的方法最先執(zhí)行。

3.調(diào)用自定義初始化方法和實現(xiàn)了InitializingBean接口的方法。

接著調(diào)用invokeInitMethods方法,里面會判斷Bean是否實現(xiàn)了InitializingBean接口,如果實現(xiàn),那么就會調(diào)用方法afterPropertiesSet(),接著會獲取Bean中自定義的初始化方法,然后通過反射調(diào)用。

從上面看出,實現(xiàn)了InitializingBean接口中的最先被執(zhí)行,自定義的Bean初始化方法第二被執(zhí)行。

4.總結(jié)

從上面看出,如果是通過@PostConstruct注解標(biāo)注的方法,則需要使用后置處理器BeanPostProcessor來進行處理,實現(xiàn)InitializingBean接口和自定義的初始化方法則不需要使用后置處理器處理,@PostConstruct標(biāo)注的方法的優(yōu)先級大于實現(xiàn)了InitializingBean接口的方法,實現(xiàn)了InitializingBean接口的方法大于自定義的初始化方法。

銷毀Bean

銷毀Bean的動作發(fā)生在容器關(guān)閉的時候,當(dāng)Spring程序中發(fā)生BeansException異常是會觸發(fā),還有我們也可以手動關(guān)閉容器,關(guān)閉容器后,Spring中的所有Bean都會被清理掉,這時候如果再去獲取對應(yīng)的Bean,就會發(fā)生異常。

1.手動關(guān)閉容器

為了去分析源碼,我們這里直接手動去關(guān)閉Spring容器,直接調(diào)用close()方法關(guān)閉容器。

手動調(diào)用關(guān)閉容器后,會去調(diào)用doClose()方法,然后里面有一個destroyBeans()方法,這里方法就是銷毀Bean,我們可以看到它有一個備注Destroy all cached singletons in the context's BeanFactory.,意思就是銷毀單例Bean,至于為什么是銷毀單例Bean,大家可以想一下,哈哈!

2.執(zhí)行標(biāo)注了@PreDestroy的方法

順著源碼一直跟進來,我們發(fā)現(xiàn)它它也會調(diào)用Bean的后置處理器,然后通過反射調(diào)用標(biāo)注了@PreDestroy注解的方法,這里和標(biāo)注了@PostConstruct的方法的執(zhí)行是一樣的。

3.調(diào)用實現(xiàn)DisposableBean接口的方法

接著判斷當(dāng)前的Bean是否實現(xiàn)了DisposableBean接口,如果實現(xiàn)了,則調(diào)用destroy()方法,和InitializingBean也是一樣的套路。

4.執(zhí)行自定義的銷毀方法

往下執(zhí)行,就會判斷是否定義了自定義的銷毀方法,如果定義了,則通過反射進行調(diào)用,和初始化方法哪里是一樣的套路。

5.總結(jié)

從上面可以看出,銷毀Bean和初始化Bean時這些擴展點的方式基本上都差不多,在銷毀Bean時,會將其中涉及到的裝Bean的一些集合都進行清空,然后再把BeanFactory關(guān)閉,不過我們這里關(guān)注的時銷毀時執(zhí)行的方法,就不去管那些了。

我們得出結(jié)論,標(biāo)注了@PreDestroy注解的方法最先被執(zhí)行,實現(xiàn)了DisposableBean接口的第二被執(zhí)行,自定義的銷毀方法最后被執(zhí)行。

五.思考

我們思考一下,為什么Spring對于@PostConstruct注解和@PreDestory注解要使用專門的后置處理器來處理?

其實這也是Spring牛逼的地方,擴展性極強,因為@PostConstruct注解和@PreDestory注解其實不是屬于Spring的,而是Java語言層面的注解,如果不通過擴展的方式來實現(xiàn)這兩個注解的使用,那么就沒有擴展性而言,加入那天再需要加入Java層面的注解到Spring中,那么又需要去代碼里面改,顯然,這樣的設(shè)計時不合理的。

像@Resource注解也不是Spring的,也是Java層面的,處理這個注解也時通過后置處理器來進行處理。

所以Spring為什么發(fā)展得這么迅猛,Java程序員基本沒人不用Spring,Spring的不斷發(fā)展,使它成為最復(fù)雜的框架,但是它的內(nèi)核設(shè)計還是十分優(yōu)秀的,如果沒有優(yōu)秀的設(shè)計,估計代碼已經(jīng)不堪入目了。

六.總結(jié)

上面我們對于Spring的Bean初始化時和銷毀時的一些操作進行了介紹并進行測試,然后分析了它們的原理,并對Spring的設(shè)計進行我個人的理解和評價。

其實對于像Spring這樣龐大的框架,學(xué)習(xí)難度還是比較大的,需要我們一遍有一遍去debug,去分析,去理解,這樣才能慢慢對它有一個了解,如果只是為了去應(yīng)付,去背,那么基本上沒用。

以上就是深入解析Spring Bean初始化時和銷毀時的擴展點的詳細內(nèi)容,更多關(guān)于Spring Bean初始化和銷毀擴展點的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • java實現(xiàn)將字符串中首字母轉(zhuǎn)換成大寫,其它全部轉(zhuǎn)換成小寫的方法示例

    java實現(xiàn)將字符串中首字母轉(zhuǎn)換成大寫,其它全部轉(zhuǎn)換成小寫的方法示例

    這篇文章主要介紹了java實現(xiàn)將字符串中首字母轉(zhuǎn)換成大寫,其它全部轉(zhuǎn)換成小寫的方法,涉及java字符串遍歷、轉(zhuǎn)換、拼接等相關(guān)操作技巧,需要的朋友可以參考下
    2019-06-06
  • 淺談SpringBoot之事務(wù)處理機制

    淺談SpringBoot之事務(wù)處理機制

    這篇文章主要介紹了淺談SpringBoot之事務(wù)處理機制,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-01-01
  • 詳解如何將已有項目改造為Spring Boot項目

    詳解如何將已有項目改造為Spring Boot項目

    本篇文章主要介紹了如何將已有項目改造為Spring Boot項目,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11
  • java+mysql模擬實現(xiàn)銀行系統(tǒng)

    java+mysql模擬實現(xiàn)銀行系統(tǒng)

    這篇文章主要為大家詳細介紹了java+mysql模擬實現(xiàn)銀行系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-05-05
  • springboot不掃描@repository的問題及解決

    springboot不掃描@repository的問題及解決

    這篇文章主要介紹了springboot不掃描@repository的問題及解決,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2024-05-05
  • 實例解析觀察者模式及其在Java設(shè)計模式開發(fā)中的運用

    實例解析觀察者模式及其在Java設(shè)計模式開發(fā)中的運用

    觀察者模式定義了一種一對多的依賴關(guān)系,讓多個觀察者對象同時監(jiān)聽某一個主題對象,這個主題對象在狀態(tài)上發(fā)生變化時,會通知所有觀察者對象,使它們能夠自動更新自己.下面就以實例解析觀察者模式及其在Java設(shè)計模式開發(fā)中的運用
    2016-05-05
  • Java解決xss轉(zhuǎn)義導(dǎo)致轉(zhuǎn)碼的問題

    Java解決xss轉(zhuǎn)義導(dǎo)致轉(zhuǎn)碼的問題

    跨站腳本攻擊XSS是最普遍的Web應(yīng)用安全漏洞,本文主要介紹了Java解決xss轉(zhuǎn)義導(dǎo)致轉(zhuǎn)碼的問題,具有一定的參考價值,感興趣的可以了解一下
    2023-08-08
  • 使用mtrace追蹤JVM堆外內(nèi)存泄露的方法

    使用mtrace追蹤JVM堆外內(nèi)存泄露的方法

    這篇文章主要給大家介紹了如何使用mtrace追蹤JVM堆外內(nèi)存泄露,文章通過代碼示例介紹的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-09-09
  • 源碼解析Java類加載器

    源碼解析Java類加載器

    這篇文章主要給大家介紹了Java類加載器源碼解析的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-12-12
  • maven的settings.xml、pom.xml配置文件使用詳解

    maven的settings.xml、pom.xml配置文件使用詳解

    本文詳解了Maven中的配置文件settings.xml和pom.xml,闡述了它們的作用、配置項以及優(yōu)先級順序,settings.xml存在于Maven安裝目錄和用戶目錄下,分別作用于全局和當(dāng)前用戶,pom.xml位于項目根路徑下
    2024-09-09

最新評論