細(xì)說Spring——IoC詳解(XML配置二)

我們書接上文:細(xì)說Spring——IoC詳解(四)草慧,接著講解配置文件。

一、<bean>中的屬性

1宗收、depends-on

我們可以用depends-on屬性來聲明當(dāng)前的對象所依賴的對象挂疆,比如我們當(dāng)前的對象A在構(gòu)造時(shí)調(diào)用了對象B的一個(gè)方法改览,那么我們就可以使用depends-on來聲明這種依賴下翎,然后在容器構(gòu)造對象A之前就會先去構(gòu)造對象B,同時(shí)可以在depends-on中通過逗號分割各個(gè)beanName宝当,來達(dá)到多個(gè)依賴的效果视事,示例如下:

<bean id="classAInstance" class="...ClassA" depends-on="configSetup,configSetup2,..."/>
<bean id="configSetup" class="SystemConfigurationSetup"/>
<bean id="configSetup2" class="SystemConfigurationSetup2"/> 
2、autowire

通過<bean>autowire屬性庆揩,可以指定當(dāng)前bean定義采用某種類型的自動綁定模式俐东。也就是可以幫助我們自動的注入依賴,而不用使用<constructor-arg><property>來顯式的聲明依賴订晌。
Spring提供了5種自動綁定模式虏辫,即no、byName锈拨、byType砌庄、constructor和autodetect,下面是它們的具體介紹:

  • no:容器默認(rèn)的自動綁定模式奕枢,也就是不采用任何形式的自動綁定娄昆,完全依賴手工明確配置各個(gè)bean之間的依賴關(guān)系,以下代碼演示的兩種配置是等效的:<bean id="beanName" class="..."/>或者<bean id="beanName" class="..." autowire="no"/>
  • byName:按照類中聲明的實(shí)例變量的名稱缝彬,與XML配置文件中聲明的bean定義的beanName的值進(jìn)行匹配萌焰,相匹配的bean定義將被自動綁定到當(dāng)前實(shí)例變量上。這種方式對類定義和配置的bean定義有一定的限制谷浅。假設(shè)我們有如下所示的類定義:
public class Foo
{
 private Bar emphasisAttribute;
 ...
 // 相應(yīng)的setter方法定義
}
public class Bar
{
 ...
}

那么應(yīng)該使用如下代碼所演示的自動綁定定義扒俯,才能達(dá)到預(yù)期的目的:

<bean id="fooBean" class="...Foo" autowire="byName">
</bean>
<bean id="emphasisAttribute" class="...Bar">
</bean>

需要注意兩點(diǎn):第一,我們并沒有明確指定fooBean的依賴關(guān)系一疯,而僅指定了它的autowire屬性
為byName撼玄;第二,第二個(gè)bean定義的id為emphasisAttribute违施,與Foo類中的實(shí)例變量名稱相同互纯。

  • byType:如果指定當(dāng)前bean定義的autowire模式為byType,那么磕蒲,容器會根據(jù)當(dāng)前bean定義類型留潦,分析其相應(yīng)的依賴對象類型,然后到容器所管理的所有bean定義中尋找與依賴對象類型相同的bean定義辣往,然后將找到的符合條件的bean自動綁定到當(dāng)前bean定義兔院。對于byName模式中的實(shí)例類Foo來說,容器會在其所管理的所有bean定義中尋找類型為Bar的bean定義站削。如果找到坊萝,則將找到的bean綁定到Foo的bean定義;如果沒有找到,則不做設(shè)置十偶。但如果找到多個(gè)菩鲜,容器會告訴你它解決不了“該選用哪一個(gè)”的問題,你只好自己查找原因惦积,并自己修正該問題接校。所以,byType只能保證狮崩,在容器中只存在一個(gè)符合條件的依賴對象的時(shí)候才會發(fā)揮最大的作用蛛勉,如果容器中存在多個(gè)相同類型的bean定義,那么睦柴,不好意思诽凌,采用手動明確配置吧!指定byType類型的autowire模式與byName沒什么差別坦敌,只是autowire的值換成byType而已侣诵,可
    以參考如下代碼:
<bean id="fooBean" class="...Foo" autowire="byType">
</bean>
<bean id="anyName" class="...Bar"> </bean>
  • constructor:byName和byType類型的自動綁定模式是針對property的自動綁定,而constructor類型則是針對構(gòu)造方法參數(shù)的類型而進(jìn)行的自動綁定恬试,它同樣是byType類型的綁定模式窝趣。不過疯暑,constructor是匹配構(gòu)造方法的參數(shù)類型训柴,而不是實(shí)例屬性的類型。與byType模式類似妇拯,如果找到不止一個(gè)符合條件的bean定義幻馁,那么,容器會返回錯(cuò)誤越锈。使用上也與byType沒有太大差別仗嗦,只不過是應(yīng)用到需要使用構(gòu)造方法注入的bean定義之上,示例如下:
public class Foo
{
    private Bar bar;
    public Foo(Bar arg)
     {
        this.bar = arg;
     }
 ...
}
相應(yīng)配置為
<bean id="foo" class="...Foo" autowire="constructor"/>
<bean id="bar" class="...Bar">
</bean> 
  • autodetect:這種模式是byType和constructor模式的結(jié)合體甘凭,如果對象擁有默認(rèn)無參數(shù)的構(gòu)造方法稀拐,容器會優(yōu)先考慮byType的自動綁定模式。否則丹弱,會使用constructor模式德撬。當(dāng)然,如果通過構(gòu)造方法注入綁定后還有其他屬性沒有綁定躲胳,容器也會使用byType對剩余的對象屬性進(jìn)行自動綁定蜓洪。

<beans>有一個(gè)default-autowire屬性,它可以幫我們省去為多個(gè)<bean>單獨(dú)設(shè)置autowire屬性的麻煩坯苹,default-autowire的默認(rèn)值為no隆檀,即不進(jìn)行自動綁定。

3、dependency-check

我們可以使用每個(gè)<bean>dependency-check屬性對其所依賴的對象進(jìn)行最終檢查恐仑,該功能可以幫我們檢查每個(gè)對象某種類型的所有依賴是否全部已經(jīng)注入完成泉坐,不過可能無法細(xì)化到具體的類型檢查。有如下4種類型的依賴檢查:

  • none:不做依賴檢查裳仆。將dependency-check指定為none跟不指定這個(gè)屬性等效坚冀,所以,還是不要多敲那幾個(gè)字符了吧鉴逞。默認(rèn)情況下记某,容器以此為默認(rèn)值。
  • simple:如果將dependency-check的值指定為simple构捡,那么容器會對簡單屬性類型以及相
    關(guān)的collection進(jìn)行依賴檢查液南,對象引用類型的依賴除外。
  • object:只對對象引用類型依賴進(jìn)行檢查勾徽。
  • all:將simple和object相結(jié)合滑凉,也就是說會對簡單屬性類型以及相應(yīng)的collection和所有對
    象引用類型的依賴進(jìn)行檢查。
4喘帚、 lazy-init

延遲初始化畅姊,這個(gè)主要作用于ApplicationContext容器BeanFactory容器的初始化策略默認(rèn)是延遲初始化吹由。<beans>中也有一個(gè) default-lazy-init屬性若未,可以統(tǒng)一控制所有的<beans>進(jìn)行延遲初始化。示例如下:

<beans default-lazy-init="true">
     <bean id="lazy-init-bean" class="..." lazy-init="false"/>
     <bean id="not-lazy-init-bean" class="...">
         <property name="propName">
             <ref bean="lazy-init-bean"/>
         </property>
    </bean>
 ...
</beans> 

好了到了這里<bean>中比較一般的屬性就介紹完了倾鲫,接下來是一些比較重要的屬性粗合,我們就著重來看一下。

5乌昔、abstractparent

在面向?qū)ο蟮木幊淘碇邢毒危?dāng)多個(gè)類擁有相同的方法和屬性,則可以引入父類消除代碼重復(fù)磕道。在Spring容器中供屉,如果多個(gè)Bean存在相同的配置信息,同樣可以定義一個(gè)父Bean溺蕉,子Bean將自動繼承父Bean的配置信息伶丐。父bean中的所有屬性值也會出現(xiàn)在子bean當(dāng)中,那么假如子bean當(dāng)中配置了父bean已有的屬性的話焙贷,會覆蓋掉父bean中的配置撵割。我們可以通過<parent>來指定繼承關(guān)系,示例如下:
1辙芍、 未使用父子<bean>的配置

    <bean id=“car1” class=“cn.lovepi.***.Car”  
     p:brand=“奔馳E300” p:price=“2000” p:color=“黑色”/>  
     
    <bean id=“car1” class=“cn.lovepi.***.Car”  
     p:brand=“奔馳E300” p:price=“2000” p:color=“紅色”/>  

可以看到啡彬,兩個(gè)car bean除了color屬性不同之外羹与,其他屬性都是完全一樣的。

2庶灿、使用父子<bean>的配置

<bean id=“abstractCar” class=“cn.lovepi.***.Car”  
     p:brand=“奔馳E300” p:price=“2000” p:color=“黑色” abstract=“true”/>  
<bean id=“car1” p:color=“紅色” parent=“abstractCar” />  
<bean id=“car1” p:color=“白色” parent=“abstractCar” />  

可以看到car1和car2這兩個(gè)bean都繼承自abstractCar這個(gè)父bean纵搁,在上面的代碼中子bean就只改變了color屬性,其他屬性都跟父類相同往踢。

通過abstract屬性聲明為true腾誉,說明這個(gè)bean定義不需要實(shí)例化。峻呕。如果你不想容器在初始化的時(shí)候?qū)嵗承ο罄埃敲纯梢詫⑵鋋bstract屬性賦值true,以避免容器將其實(shí)例化瘦癌。對于ApplicationContext容器尤其如此猪贪,因?yàn)槟J(rèn)情況下,ApplicationContext會在容器啟動的時(shí)候就對其管理的所有bean進(jìn)行實(shí)例化讯私,只有標(biāo)志為abstract的bean和設(shè)定為延遲加載的bean除外热押。

6、scope

這里就在偷個(gè)懶吧斤寇,貼個(gè)鏈接:Spring學(xué)習(xí)(十五)Spring Bean 的5種作用域介紹
這個(gè)博客詳細(xì)的講解了<bean>scope屬性桶癣。

7娘锁、factory-methodfactory-bean

這里就需要介紹致盟,依賴的注入除了我們常用的構(gòu)造器方法注入和setter方法注入以外,還可以使用工廠方法進(jìn)行注入杯道,這里分為了兩種责蝠,一個(gè)是靜態(tài)工廠方法注入霜医,一個(gè)是非靜態(tài)工廠方法注入,下面就分別介紹一下吧:

  • 靜態(tài)工廠方法注入
public class StaticBarInterfaceFactory
{
     public static BarInterface getInstance()
     { 
      return new BarInterfaceImpl();
     }
} 

為了將該靜態(tài)工廠方法類返回的實(shí)現(xiàn)注入Foo署海,我們使用以下方式進(jìn)行配置

<bean id="foo" class="...Foo">
     <property name="barInterface">
         <ref bean="bar"/>
     </property>
</bean>
<bean id="bar" class="...StaticBarInterfaceFactory" factory-method="getInstance"/> 

class指定靜態(tài)方法工廠類捻勉,factory-method指定工廠方法名稱踱启,然后,容器調(diào)用該靜態(tài)方法工
廠類的指定工廠方法(getInstance)榜晦,并返回方法調(diào)用后的結(jié)果胚想,即BarInterfaceImpl的實(shí)例。
也就是說胚吁,為foo注入的bar實(shí)際上是BarInterfaceImpl的實(shí)例牙躺,即方法調(diào)用后的結(jié)果孽拷,而不是靜態(tài)工廠方法類(StaticBarInterfaceFactory)窿侈。

  • 非靜態(tài)工廠方法注入
public class NonStaticBarInterfaceFactory
{
    public BarInterface getInstance()
     {
         return new BarInterfaceImpl();
     }
 ...
}
<bean id="foo" class="...Foo">
     <property name="barInterface">
         <ref bean="bar"/>
     </property>
</bean>
<bean id="barFactory" class="...NonStaticBarInterfaceFactory"/>
<bean id="bar" factory-bean="barFactory" factory-method="getInstance"/> 

NonStaticBarInterfaceFactory是作為正常的bean注冊到容器的史简,而bar的定義則與靜態(tài)工廠方
法的定義有些不同。現(xiàn)在使用factory-bean屬性來指定工廠方法所在的工廠類實(shí)例刀脏,而不是通過
class屬性來指定工廠方法所在類的類型愈污。指定工廠方法名則相同茫陆,都是通過factory-method屬性進(jìn)行的桨醋。

二瞬内、總結(jié)

這里就對<bean>標(biāo)簽中的屬性進(jìn)行一個(gè)總結(jié):

  • Id:通過id來訪問SpringBeanFactory中的java bean
  • name: 通過name來訪問SpringBeanFactory中的java bean限书,在某種意義上來講name就是id的別稱虫蝶。
  • class:java bean定義的全限定名,即包名+類名倦西。假如配置文件中沒有指定id或name的取值能真,那么class即作為id的取值。
  • parent:如果沒有指定class屬性的話則可以使用parent扰柠,他們的含義是等效的粉铐。而且parent java bean 定義不僅能夠繼承parent當(dāng)中定義的所有內(nèi)容,而且還能夠覆蓋parent當(dāng)中定義的相關(guān)內(nèi)容卤档。比如覆蓋java bean方法:init蝙泼、destory等內(nèi)容。當(dāng)然某些parent設(shè)置是不能被覆蓋的裆装,比如:依賴關(guān)系踱承、autowire的值、作用域哨免。
  • abstract:當(dāng)值為true的時(shí)候,表明相應(yīng)的java bean定義只是供parent使用昙沦,其本身是不能夠被實(shí)例化的琢唾。默認(rèn)值為false。
  • scope:bean的作用域盾饮,Spring當(dāng)中提供了5種作用域采桃。
  • lazy-init:延遲加載屬性懒熙,只有當(dāng)用到這個(gè)bean的時(shí)候,Spring才會進(jìn)行實(shí)例化普办。
  • autowire:開發(fā)者是否使用Spring提供的autowire功能工扎,建議不使用,默認(rèn)值為no
  • dependency-check:Spring是否需要對java bean 以及java bean之間的依賴關(guān)系來進(jìn)行判斷衔蹲。定義此屬性將會覆蓋在beans中定義的default-dependency-check屬性肢娘。
  • depends-on:用于保證相應(yīng)的java bean在其指定depends-on的java bean實(shí)例化之后,才去實(shí)例化使用了depends-on的java bean的本身舆驶。
  • init-method:主要用于設(shè)置在實(shí)例化java bean橱健,并設(shè)置java bean的屬性之后,待執(zhí)行的初始化方法沙廉。
  • destroy-method:當(dāng)中SpringBeanFactory銷毀的時(shí)候,可以利用此方法來進(jìn)行一些資源回收的操作拘荡。或者一些其他的操作撬陵,比如關(guān)閉同GMS目的地的監(jiān)聽以及連接珊皿。在這里請注意,指令的方法應(yīng)該是參數(shù)類型巨税。
  • factory-method:指定用于創(chuàng)建java bean 工廠的methed方法亮隙。在Spring當(dāng)中,對象的創(chuàng)建最好是通過bean factory來創(chuàng)建垢夹。
  • factory-bean:指定用于創(chuàng)建java bean實(shí)例的工廠類溢吻。
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市果元,隨后出現(xiàn)的幾起案子促王,更是在濱河造成了極大的恐慌,老刑警劉巖而晒,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝇狼,死亡現(xiàn)場離奇詭異,居然都是意外死亡倡怎,警方通過查閱死者的電腦和手機(jī)迅耘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來监署,“玉大人颤专,你說我怎么就攤上這事∧品Γ” “怎么了栖秕?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長晓避。 經(jīng)常有香客問我簇捍,道長只壳,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任暑塑,我火速辦了婚禮吼句,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘事格。我一直安慰自己惕艳,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布分蓖。 她就那樣靜靜地躺著尔艇,像睡著了一般。 火紅的嫁衣襯著肌膚如雪么鹤。 梳的紋絲不亂的頭發(fā)上终娃,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音蒸甜,去河邊找鬼棠耕。 笑死,一個(gè)胖子當(dāng)著我的面吹牛柠新,可吹牛的內(nèi)容都是我干的窍荧。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼恨憎,長吁一口氣:“原來是場噩夢啊……” “哼蕊退!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起憔恳,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤瓤荔,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后钥组,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體输硝,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年程梦,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了点把。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡屿附,死狀恐怖郎逃,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情拿撩,我是刑警寧澤衣厘,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布,位于F島的核電站压恒,受9級特大地震影響影暴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜探赫,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一型宙、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧伦吠,春花似錦妆兑、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至箱靴,卻和暖如春腺逛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背衡怀。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工棍矛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人抛杨。 一個(gè)月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓够委,卻偏偏與公主長得像,于是被迫代替她去往敵國和親怖现。 傳聞我的和親對象是個(gè)殘疾皇子茁帽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 1.1 spring IoC容器和beans的簡介 Spring 框架的最核心基礎(chǔ)的功能是IoC(控制反轉(zhuǎn))容器,...
    simoscode閱讀 6,701評論 2 22
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理屈嗤,服務(wù)發(fā)現(xiàn)潘拨,斷路器,智...
    卡卡羅2017閱讀 134,601評論 18 139
  • 文章作者:Tyan博客:noahsnail.com 3.4 Dependencies A typical ente...
    SnailTyan閱讀 4,128評論 2 7
  • 文章作者:Tyan博客:noahsnail.com 3.4 依賴 標(biāo)準(zhǔn)企業(yè)應(yīng)用不會由一個(gè)對象(或Spring用語中...
    SnailTyan閱讀 1,170評論 0 1
  • 通過上師在發(fā)心人員的年會上總結(jié)了他弘法三十年的成果恢共,并給學(xué)會的發(fā)心人員提出的一些建議和要求以及忠告战秋。在這樣一個(gè)時(shí)代...
    緣孟閱讀 236評論 0 0