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

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

什麼是Bean

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

<code>In Spring, the objects that form the backbone of your application and that are managed 

by

the Spring IoC container are called beans. A bean

is

an

object

that

is

instantiated, assembled, and otherwise managed

by

a Spring IoC container. Otherwise, a bean

is

simply one of many objects

in

your application /<code>

從上面可知,我們可以給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的生命週期

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

<code>

Bean

自身的方法

Bean

級生命週期方法 容器級的方法(BeanPostProcessor一系列接口) 工廠後處理器方法(

BeanFactoryProcessor

一系列接口) /<code>

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該接口有兩個方法:
<code>初始化之前
初始化之後
/<code>

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

  1. InstantiationAwareBeanPostProcessor該類是BeanPostProcessor的子接口,常用的有如下三個方法
<code>實例化之前
實例化之後、設置屬性前
實例化之後
/<code>

測試Bean生命週期

下面我們來編寫一個實例來驗證我們上面所說的Bean生命週期

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

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

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

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

實現自己的
InstantiationAwareBeanPostProcessor

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

xml配置文件如下

<code>

<

context:component-scan

base-package

=

"com.xiaohuan.springtest"

/>

<

bean

id

=

"user"

class

=

"com.xiaohuan.springtest.beanlifecycle.User"

init-method

=

"myInit"

destroy-method

=

"myDestroy"

>

<

constructor-arg

index

=

"0"

type

=

"int"

>

<

value

>

1

value

>

constructor-arg

>

<

constructor-arg

index

=

"1"

type

=

"java.lang.String"

>

<

value

>

xiaohuan

value

>

constructor-arg

>

<

property

name

=

"id"

value

=

"2"

/>

<

property

name

=

"name"

value

=

"dahuan"

/>

bean

>

複製代碼/<code>

編寫我們自己的測試類

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

最後運行項目

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


分享到:


相關文章: