天天看點

一文詳解Spring中Bean的生命周期

雲栖号資訊:【 點選檢視更多行業資訊

在這裡您可以找到不同行業的第一手的上雲資訊,還在等什麼,快來!

在Spring中,Bean是最基礎的對象,一切操作都是圍繞Bean展開的。Spring是一個BOP(Bean Oriented Programming)架構,Bean在BOP中的作用就像是對象在OOP中的作用一樣。既然如此重要,那麼我們首先需要了解到底什麼是Bean?

什麼是Bean

首先,我們來看看Spring官方文檔對于Bean的定義:

一文詳解Spring中Bean的生命周期

從上面可知,我們可以給Bean下一個定義:Bean就是由IOC執行個體化、組裝、管理的一個對象。

Bean的生命周期

我們需要明确的是,在這裡我們的Bean的生命周期主要指的是singleton bean,對prototype bean來說,當使用者getBean獲得prototype bean的執行個體後,IOC容器就不再對目前執行個體進行管理,而是把管理權交由使用者,此後再getBean生成的是新的執行個體。對于request/session/application/websocket 這幾種scope的bean我們在此不談。

在不同的容器中,Bean的生命周期開始的時間不同。對于ApplicationContext來說,當容器啟動的時候,bean就已經執行個體化了。而對于BeanFactory來說,直到調用getBean()方法的時候才進行執行個體化。

我們知道對于普通的java對象來說,它們的生命周期就是

  • 執行個體化
  • 不再使用的時候通過垃圾回收機制進行回收

但是對于Bean來說卻不是這樣。Bean的生命周期如下圖所示

一文詳解Spring中Bean的生命周期

對于如上這些方法,我們可以分成如下幾類

1.Bean自身的方法:比如構造函數、getter/setter以及init-method和destory-method所指定的方法等

2.Bean級生命周期方法:可以了解為Bean類直接實作接口的方法,比如BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean、DisposableBean等方法,這些方法隻對目前Bean生效

3.容器級的方法(BeanPostProcessor一系列接口):主要是後處理器方法,比如上圖的InstantiationAwareBeanPostProcessor、BeanPostProcessor接口方法。這些接口的實作類是獨立于bean的,并且會注冊到Spring容器中。在Spring容器建立任何Bean的時候,這些後處理器都會發生作用。

4.工廠後處理器方法(BeanFactoryProcessor一系列接口):包括AspectJWeavingEnabler、CustomAutowireConfigurer、ConfigurationClassPostProcessor等。這些都是Spring架構中已經實作好的BeanFactoryPostProcessor,用來實作某些特定的功能。

Bean自身的方法和Bean級生命周期方法都隻對目前Bean起作用,但是容器級生命周期方法和工廠後處理器方法是對所有的bean都起作用。

對于這幾類方法,1 2 4都很好了解,下面我們重點來說一下什麼是BeanPostProcessor和BeanFactoryPostProcessor

以我個人了解來說,BeanPostProcessor和BeanFactoryPostProcessor就是Spring建立的擴充點,使用者可以建立自己的實作類來修改Bean或者BeanFactory

注意對于ApplicatonContext來說,容器可以自動檢測并加載BeanPostProcessor和BeanFactoryPostProcessor,但是BeanFactory不行,需要自己調用方法手動注冊。BeanPostProcessor和BeanFactoryPostProcessor都可以有多個。ApplicationContext也可以根據org.springframework.core.PriorityOrdered和org.springframework.core.Ordered來進行自定義排序,但是BeanFactory不可以,預設順序就是注冊順序。

這裡我需要說明下面兩個容易混淆的單詞:

  • Instantiation:執行個體化,指的是調用構造函數進行執行個體化
  • Initialization:初始化,在Bean的聲明周期中指的是init-method所指定的方法或者是InitializingBean.afterPropertiesSet()方法

下面我們對常用的這些接口進行說明:

常用接口說明

1.BeanNameAware

該接口隻有一個方法setBeanName(String name),用來擷取bean的id或者name

2.BeanFactoryAware

該接口隻有一個方法setBeanFactory(BeanFactory beanFactory),用來擷取目前環境中的BeanFactory

3.ApplicationContextAware

該接口隻有一個方法setApplicationContext(ApplicationContext applicationContext),用來擷取目前環境中的ApplicationContext

擷取到IOC容器之後,可以對beans進行修改等操作

4.InitializingBean

該接口隻有一個方法afterPropertiesSet(),在屬性注入完成後調用

5.DisposableBean

該接口隻有一個方法destroy(),在容器銷毀的時候調用,在使用者指定的destroy-method之前調用

6.BeanPostProcessor該接口有兩個方法:

  • postProcessBeforeInitialization(Object bean, String beanName):在初始化之前調用此方法
  • postProcessAfterInitialization(Object bean, String beanName):在初始化之後調用此方法

通過方法簽名我們可以知道,我們可以通過beanName來篩選出我們需要進行個性化定制的bean

7.InstantiationAwareBeanPostProcessor

該類是BeanPostProcessor的子接口,常用的有如下三個方法

  • postProcessBeforeInstantiation(Class beanClass, String beanName):在bean執行個體化之前調用
  • postProcessProperties(PropertyValues pvs, Object bean, String beanName):在bean執行個體化之後、設定屬性前調用
  • postProcessAfterInstantiation(Class beanClass, String beanName):在Bean執行個體化之後調用

測試Bean生命周期

下面我們來編寫一個執行個體來驗證我們上面所說的Bean生命周期

首先,我們建立一個User,這個Bean實作了我們的BeanNameAware、ApplicationContextAware、InitializingBean、DisposableBean接口

一文詳解Spring中Bean的生命周期

然後我們實作我們自己的BeanPostProcessor

一文詳解Spring中Bean的生命周期

實作自己的InstantiationAwareBeanPostProcessor

一文詳解Spring中Bean的生命周期

xml配置檔案如下

一文詳解Spring中Bean的生命周期

編寫我們自己的測試類

一文詳解Spring中Bean的生命周期

最後運作項目

一文詳解Spring中Bean的生命周期

【雲栖号線上課堂】每天都有産品技術專家分享!

課程位址:

https://yqh.aliyun.com/live

立即加入社群,與專家面對面,及時了解課程最新動态!

【雲栖号線上課堂 社群】

https://c.tb.cn/F3.Z8gvnK

原文釋出時間:2020-04-28

本文作者:寫西瓜的Code

本文來自:“

掘金

”,了解相關資訊可以關注“掘金”