鍍金池/ 教程/ Java/ Bean 之前初始化
控制反轉(zhuǎn)(IoC)/依賴注入(DI)
工廠模式
Bean 的銷毀
Bean 的定義
IoC 容器
Bean 之前初始化
設(shè)計(jì)用戶持久化類
工廠模式改進(jìn)
配置 Bean 的屬性值和 Bean 對(duì)象的組裝
BeanFactory 管理 Bean(組件)的生命周期
BeanFactory
幾種依賴注入模式的對(duì)比總結(jié)
依賴注入的三種實(shí)現(xiàn)形式
復(fù)雜的屬性值

Bean 之前初始化

Bean 工廠使用 Bean 的構(gòu)造函數(shù)創(chuàng)建 Bean 對(duì)象之后,緊接著它會(huì)做一件非常重要的工作——Bean 的初始化。它會(huì)根據(jù)配置信息設(shè)置 Bean 的屬性和依賴對(duì)象,執(zhí)行相應(yīng)的初始化方法。

自動(dòng)裝配

一般不推薦在大型的應(yīng)用系統(tǒng)中使用自動(dòng)裝配。當(dāng)然,它可以很好的用于小型應(yīng)用系統(tǒng)。如果一個(gè) Bean 聲明被標(biāo)志為“autowire(自動(dòng)裝配)”,bean 工廠會(huì)自動(dòng)將其他的受管對(duì)象與其要求的依賴關(guān)系進(jìn)行匹配,從而完成對(duì)象的裝配——當(dāng)然,只有當(dāng)對(duì)象關(guān)系無歧義時(shí)才能完成自動(dòng)裝配。因?yàn)椴恍枰鞔_指定某個(gè)協(xié)作對(duì)象,所以可以帶來很多的便利性。

舉個(gè)例子,如果在 Bean 工廠中有一個(gè)SessionFactory類型的實(shí)例,HibernateUserDao 的sessionFactory 屬性就可以獲得這個(gè)實(shí)例。這里可以使用autowire屬性,就象這樣:

<bean id="userDao" class="com.dev.spring.simple.HibernateUserDao" autowire=”byType”>

</bean>

<bean id="sessionFactory"

class="org.springframework.orm.hibernate.LocalSessionFactoryBean">

?????? …..

</bean>

注意,在userDao的定義中并沒有明確引用sessionFactory。由于它的“autowire”被設(shè)置為“byType”,所有只要userDao有一個(gè)類型為SessionFactory的屬性并有一個(gè) set 方法,Bean 工廠就會(huì)自動(dòng)將sessionFactory組裝到userDao中。

如果一個(gè)應(yīng)用有兩個(gè)數(shù)據(jù)庫(kù),這時(shí)就對(duì)應(yīng)有兩個(gè)SessionFactory。這時(shí) autowire="byType"就無法使用了。我們可以使用另外一種自動(dòng)裝配方式“byName”。它將根據(jù)屬性的名稱來匹配依賴對(duì)象,這樣如果你的配置文件中可以同時(shí)存在多個(gè)類型相同的SessionFactory,只要他們定義的名稱不同就可以了。這種方式的缺點(diǎn)是:需要精確匹配 Bean 的名稱,即必須要保證屬性的名稱和它所依賴的 Bean 的名稱相等,這樣比較容易出錯(cuò)。

(舉例:Aa 對(duì)象依賴 Bb 對(duì)象。)

注意:我們還是強(qiáng)烈推薦手工指定 Bean 之間的依賴關(guān)系。這種用法最強(qiáng)大,因?yàn)樗试S按名稱引用特定的 Bean 實(shí)例,即使多個(gè) Bean 具有相同類型也不會(huì)混淆。同時(shí),你可以清楚的知道一個(gè) Bean 到底依賴哪些其它的 Bean。如果使用自動(dòng)裝載,你只能去 Bean 的代碼中了解。甚至,Bean 工廠也許會(huì)自動(dòng)裝載一些你根本不想依賴的對(duì)象。

依賴檢查

如果你希望 Bean 嚴(yán)格的設(shè)置所有的屬性,“dependency-check”(依賴檢查)屬性將會(huì)非常有用。它默認(rèn)為“none”,不進(jìn)行依賴檢查。“simple”會(huì)核對(duì)所有的原始類型和 String 類型的屬性?!皁bjects”只做對(duì)象間的關(guān)聯(lián)檢查(包括集合)。“all”會(huì)檢查所有的屬性,包括“simple”和“objects”。

舉個(gè)例子:一個(gè) Bean 有如下的一個(gè)屬性:

private int intVar = 0;

public void setIntVar(int intVar) {

??????? this.intVar = intVar;

}

這個(gè) Bean 的配置文件設(shè)置了“dependency-check=”simple””。如果這個(gè)Bean的配置中沒有定義這個(gè)屬性“intVar”,則在進(jìn)行這個(gè) Bean 的依賴檢查時(shí)就會(huì)拋出異常:org.springframework.beans.factory.UnsatisfiedDependencyException。

setXXX()

set方法非常簡(jiǎn)單,它會(huì)給 class 注入所有依賴的屬性。這些屬性都必須是在配置文件中使用元素定義,它們可以是原始類型,對(duì)象類型(Integer,Long),null 值,集合,其它對(duì)象的引用。

afterPropertiesSet()

有兩種方法可以實(shí)現(xiàn) Bean 的之前初始化方法。

  • 使用“init-method”屬性,在 Spring 的配置文件中定義回調(diào)方法。下面將會(huì)具體描述。
  • 實(shí)現(xiàn)接口InitializingBean并實(shí)現(xiàn)它的afterPropertiesSet()方法。接口InitializingBean的代碼如下:
public interface InitializingBean {

void afterPropertiesSet() throws Exception;

}

在 JavaBean 的所有屬性設(shè)置完成以后,容器會(huì)調(diào)用afterPropertiesSet()方法,應(yīng)用對(duì)象可以在這里執(zhí)行任何定制的初始化操作。這個(gè)方法允許拋出最基本的Exception異常,這樣可以簡(jiǎn)化編程模型。

在 Spring 框架內(nèi)部,很多 bean 組件都實(shí)現(xiàn)了這些回調(diào)接口。但我們的 Bean 組件最好不要通過這種方式實(shí)現(xiàn)生命周期的回調(diào),因?yàn)樗蕾囉?Spring 的 API。無疑,第一種方法是我們的最佳選擇。

init-method

init-method的功能和InitializingBean 接口一樣。它定義了一個(gè) Bean 的初始化方法,在 Bean 的所有屬性設(shè)置完成之后自動(dòng)調(diào)用。這個(gè)初始化方法不用依賴于 Spring 的任何 API。它必須是一個(gè)無參數(shù)的方法,可以拋出 Exception。

例如:我們的 Bean 組件UserManger中定義一個(gè)初始化方法init()。這樣,我們就可以在 Bean 定義時(shí)指定這個(gè)初始化方法:

<bean id=”userManger” class=”com.dev.spring.um.DefaultUserManager”

init-method=”init”>

……

</bean>

Bean 的準(zhǔn)備就緒(Ready)狀態(tài)

Bean 完成所有的之前初始化之后,就進(jìn)入了準(zhǔn)備就緒(Ready)狀態(tài)。這就意味著你的應(yīng)用程序可以取得這些 Bean,并根據(jù)需要使用他們。

上一篇:Bean 的銷毀下一篇:BeanFactory