9.3.3、Bean的生命周期

1、Bean的作用域


在配置文件中用屬性scope標(biāo)注

(1)標(biāo)注scope為singleton或者缺省scope屬性的Bean在ApplicationContext(IOC容器為BeanFactory非ApplicationContext實(shí)現(xiàn)類則不會(huì))啟動(dòng)時(shí)就會(huì)自動(dòng)實(shí)例化,并且從容器啟動(dòng)到銷毀只存在一個(gè)實(shí)例,容器負(fù)責(zé)這個(gè)實(shí)例的全部生命周期的管理。

(2)標(biāo)注scope為prototype的Bean只在IOC容器的getBean()方法被調(diào)用時(shí)才會(huì)進(jìn)行實(shí)例化,并且每次調(diào)用該方法返回的都是不同的實(shí)例。

(3)標(biāo)注socpe為request的Bean對(duì)于每一次request都將產(chǎn)生不同Bean實(shí)例,并且在一次request結(jié)束后Bean的實(shí)例將銷毀。

(4)標(biāo)注scope為session的Bean對(duì)于每次session會(huì)話都只產(chǎn)生一個(gè)Bean實(shí)例,并且在session失效后自動(dòng)銷毀。

(5)當(dāng)一個(gè)bean的作用域?yàn)镚lobal Session,表示在一個(gè)全局的HTTP Session中,一個(gè)bean定義對(duì)應(yīng)一個(gè)實(shí)例。典型情況下,僅在使用portlet context的時(shí)候有效。該作用域僅在基于web的Spring ApplicationContext情形下有效。

需要注意的是,后面三種作用域只針對(duì)web應(yīng)用。


2、Bean的生命周期

Bean實(shí)例生命周期的執(zhí)行過程如下:

Spring對(duì)bean進(jìn)行實(shí)例化,默認(rèn)bean是單例;

Spring對(duì)bean進(jìn)行依賴注入;

如果bean實(shí)現(xiàn)了BeanNameAware接口,spring將bean的id傳給setBeanName()方法;

如果bean實(shí)現(xiàn)了BeanFactoryAware接口,spring將調(diào)用setBeanFactory方法,將BeanFactory實(shí)例傳進(jìn)來(lái);

如果bean實(shí)現(xiàn)了ApplicationContextAware接口,它的setApplicationContext()方法將被調(diào)用,將應(yīng)用上下文的引用傳入到bean中;

如果bean實(shí)現(xiàn)了BeanPostProcessor接口,它的postProcessBeforeInitialization方法將被調(diào)用;

如果bean實(shí)現(xiàn)了InitializingBean接口,spring將調(diào)用它的afterPropertiesSet接口方法,類似的如果bean使用了init-method屬性聲明了初始化方法,該方法也會(huì)被調(diào)用;

如果bean實(shí)現(xiàn)了BeanPostProcessor接口,它的postProcessAfterInitialization接口方法將被調(diào)用;

此時(shí)bean已經(jīng)準(zhǔn)備就緒,可以被應(yīng)用程序使用了,他們將一直駐留在應(yīng)用上下文中,直到該應(yīng)用上下文被銷毀;

若bean實(shí)現(xiàn)了DisposableBean接口,spring將調(diào)用它的destroy()接口方法。同樣的,如果bean使用了destroy-method屬性聲明了銷毀方法,則該方法被調(diào)用;

不管何種作用域,容器都會(huì)調(diào)用所有對(duì)象的初始化生命周期回調(diào)方法。但對(duì)prototype而言,任何配置好的析構(gòu)生命周期回調(diào)方法都將不會(huì)被調(diào)用(在scope為prototype的Bean中配置destroy-method屬性無(wú)效)。清除prototype作用域的對(duì)象并釋放任何prototype bean所持有的昂貴資源(如數(shù)據(jù)庫(kù)連接資源),都是客戶端代碼的職責(zé)(讓Spring容器釋放被prototype作用域bean占用資源的一種可行方式是,通過使用bean的后置處理器,該處理器持有要被清除的bean的引用)。

例子:

定義兩個(gè)類Source、JuiceMaker,都實(shí)現(xiàn)BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean接口。

定義類MyPostProcessorImpl實(shí)現(xiàn)BeanPostProcessor接口、MyDisposableImpl實(shí)現(xiàn)DisposableBean接口

代碼如下:

Source:

public class Source implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean{

private String fruit;

private String sugar;

private String size;

/**getter and setter*/

.....

public void setBeanName(String name) {

System.out.println("【Source】調(diào)用BeanNameAware接口的setBeanName方法");

}

public void setBeanFactory(BeanFactory beanFactory) throws BeansException {

System.out.println("【Source】調(diào)用BeanFactory接口的setBeanFactory方法");

}

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

System.out.println("【Source】調(diào)用ApplicationContext接口的setApplicationContext方法");

}

public void afterPropertiesSet() throws Exception {

System.out.println("【Source】調(diào)用InitializingBean接口的afterPropertiesSet方法");

}

//自定義初始化和銷毀方法

public void init() {

System.out.println("【Source】調(diào)用自定義初始化方法初始化");

}

public void destroy() {

System.out.println("【Source】調(diào)用自定義銷毀方法");

}

}

JuiceMaker的代碼和Source類似就不貼出來(lái)了,下面來(lái)看MyPostProcessorImpl和MyDisposableImpl的代碼:

MyPostProcessorImpl:

public class MyPostProcessorImpl implements BeanPostProcessor{

public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {

System.out.println("【MyPostProcessor】" + bean.getClass().getSimpleName() + "的對(duì)象" + beanName + "開始初始化");

return bean;

}

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {

System.out.println("【MyPostProcessor】" + bean.getClass().getSimpleName() + "的對(duì)象" + beanName + "初始化完成");

return bean;

}

}

MyDisposableImpl:

public class MyDisposableImpl implements DisposableBean{

public void destroy() throws Exception {

? System.out.println("【MyDisposableImpl】調(diào)用DisposableBean接口destroy方法");

}

}

在配置文件中配置bean:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

? ? xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

? ? xsi:schemaLocation="http://www.springframework.org/schema/beans

? ? http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">

<bean id="source" class="spring.chapter9.ioc.Source" init-method="init" destroy-method="destroy">

<property name="fruit" value="橙子" ></property>

<property name="sugar" value="三勺" />

<property name="size"? value="大杯" />

</bean>

<bean id="juiceMaker" class="spring.chapter9.ioc.JuiceMaker" init-method="init" destroy-method="destroy">

? ? <property name="shopName" value="布拉格" />

? ? <property name="source"? ref="source" />

</bean>

<bean id="beanPostProcessor" class="spring.chapter9.lifecycle.MyPostProcessorImpl" />

<bean id="beanDisposable" class="spring.chapter9.lifecycle.MyDisposableImpl" />

</beans>

注意加粗的部分,分別給bean指定自定義的初始化和銷毀方法.

測(cè)試:

public class Test {

private static ApplicationContext ctx;

public static void main(String[] args) {

ctx =

new ClassPathXmlApplicationContext("classpath:spring-cfg-ioc.xml");

JuiceMaker juiceMaker = (JuiceMaker) ctx.getBean("juiceMaker");

juiceMaker.make();

}


由此可見BeanNameAware、BeanFactoryAware、ApplicationContextAware、InitializingBean接口都是針對(duì)單個(gè)Bean而言的,而BeanPostProcessor接口則是針對(duì)每一個(gè)Bean(當(dāng)然不包括實(shí)現(xiàn)了這個(gè)接口的Bean本身)。DisposableBean是針對(duì)Spring IoC容器的。

另外需要注意的是,afterPropertiesSet方法執(zhí)行完后,如果沒有自定義初始化方法,那么Bean的初始化和依賴注入已經(jīng)完成了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 1.1 spring IoC容器和beans的簡(jiǎn)介 Spring 框架的最核心基礎(chǔ)的功能是IoC(控制反轉(zhuǎn))容器,...
    simoscode閱讀 6,846評(píng)論 2 22
  • 1.1 Spring IoC容器和bean簡(jiǎn)介 本章介紹了Spring Framework實(shí)現(xiàn)的控制反轉(zhuǎn)(IoC)...
    起名真是難閱讀 2,670評(píng)論 0 8
  • 文章作者:Tyan博客:noahsnail.com 3.5 Bean scopes When you create...
    SnailTyan閱讀 2,001評(píng)論 0 1
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,544評(píng)論 19 139
  • 一、有序列表、無(wú)序列表、自定義列表如何使用?寫個(gè)簡(jiǎn)單的例子。三者在語(yǔ)義上有什么區(qū)別?在哪些情況下使用哪種(重要)?...
    崔敏嫣閱讀 427評(píng)論 0 0

友情鏈接更多精彩內(nèi)容