Bean的自動(dòng)裝配

1无午、自動(dòng)裝配說明

  • 自動(dòng)裝配是使用spring滿足bean依賴的一種方法

  • spring會(huì)在應(yīng)用上下文中為某個(gè)bean尋找其依賴的bean恨胚。

  • Spring中bean有三種裝配機(jī)制,分別是:

  1. 在xml中顯式配置矾瑰;
  2. 在java中顯式配置坦敌;
  3. 隱式的bean發(fā)現(xiàn)機(jī)制和自動(dòng)裝配。

Spring的自動(dòng)裝配需要從兩個(gè)角度來實(shí)現(xiàn)希坚,或者說是兩個(gè)操作:

  1. 組件掃描(component scanning):spring會(huì)自動(dòng)發(fā)現(xiàn)應(yīng)用上下文中所創(chuàng)建的bean边苹;
  2. 自動(dòng)裝配(autowiring):spring自動(dòng)滿足bean之間的依賴,也就是我們說的IoC/DI裁僧;

組件掃描和自動(dòng)裝配組合發(fā)揮巨大威力个束,使得顯示的配置降低到最少慕购。

推薦不使用自動(dòng)裝配xml配置 , 而使用注解 .

2、測試環(huán)境搭建

1茬底、新建一個(gè)項(xiàng)目

2沪悲、新建兩個(gè)實(shí)體類,Cat Dog 都有一個(gè)叫的方法

public class Cat {
   public void shout() {
       System.out.println("miao~");
  }
}
public class Dog {
   public void shout() {
       System.out.println("wang~");
  }

3阱表、新建一個(gè)用戶類 User

public class User {
   private Cat cat;
   private Dog dog;
   private String str;
}

4殿如、編寫Spring配置文件

<?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.xsd">

   <bean id="dog" class="com.kuang.pojo.Dog"/>
   <bean id="cat" class="com.kuang.pojo.Cat"/>

   <bean id="user" class="com.kuang.pojo.User">
       <property name="cat" ref="cat"/>
       <property name="dog" ref="dog"/>
       <property name="str" value="qinjiang"/>
   </bean>
</beans>

5、測試

public class MyTest {
   @Test
   public void testMethodAutowire() {
       ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
       User user = (User) context.getBean("user");
       user.getCat().shout();
       user.getDog().shout();
  }
}

結(jié)果正常輸出最爬,環(huán)境OK

3涉馁、byName

autowire byName (按名稱自動(dòng)裝配)

由于在手動(dòng)配置xml過程中,常常發(fā)生字母缺漏和大小寫等錯(cuò)誤爱致,而無法對其進(jìn)行檢查烤送,使得開發(fā)效率降低。

采用自動(dòng)裝配將避免這些錯(cuò)誤蒜鸡,并且使配置簡單化胯努。

測試:

1、修改bean配置逢防,增加一個(gè)屬性 autowire="byName"

<bean id="user" class="com.nie.pojo.User" autowire="byName">
   <property name="str" value="nie"/>
</bean>

2叶沛、再次測試,結(jié)果依舊成功輸出忘朝!

3灰署、我們將 cat 的bean id修改為 catXXX

4、再次測試局嘁, 執(zhí)行時(shí)報(bào)空指針java.lang.NullPointerException溉箕。因?yàn)榘碽yName規(guī)則找不對應(yīng)set方法,真正的setCat就沒執(zhí)行悦昵,對象就沒有初始化肴茄,所以調(diào)用時(shí)就會(huì)報(bào)空指針錯(cuò)誤。

小結(jié):

當(dāng)一個(gè)bean節(jié)點(diǎn)帶有 autowire byName的屬性時(shí)但指。

  1. 將查找其類中所有的set方法名寡痰,例如setCat,獲得將set去掉并且首字母小寫的字符串棋凳,即cat拦坠。

  2. 去spring容器中尋找是否有此字符串名稱id的對象。

  3. 如果有剩岳,就取出注入贞滨;如果沒有,就報(bào)空指針異常拍棕。

3晓铆、byType

autowire byType (按類型自動(dòng)裝配)

使用autowire byType首先需要保證:同一類型的對象勺良,在spring容器中唯一。如果不唯一尤蒿,會(huì)報(bào)不唯一的異常郑气。

NoUniqueBeanDefinitionException

測試:

1、將user的bean配置修改一下 : autowire="byType"

2腰池、測試尾组,正常輸出

3、在注冊一個(gè)cat 的bean對象示弓!

<bean id="dog" class="com.nie.pojo.Dog"/>
<bean id="cat" class="com.nie.pojo.Cat"/>
<bean id="cat2" class="com.nie.pojo.Cat"/>

<bean id="user" class="com.nie.pojo.User" autowire="byType">
   <property name="str" value="nie"/>
</bean>

4讳侨、測試,報(bào)錯(cuò):NoUniqueBeanDefinitionException

5奏属、刪掉cat2跨跨,將cat的bean名稱改掉!測試囱皿!因?yàn)槭前搭愋脱b配勇婴,所以并不會(huì)報(bào)異常,也不影響最后的結(jié)果嘱腥。甚至將id屬性去掉耕渴,也不影響結(jié)果。

這就是按照類型自動(dòng)裝配

4齿兔、使用注解實(shí)現(xiàn)自動(dòng)裝配

jdk1.5開始支持注解橱脸,spring2.5開始全面支持注解。

1分苇、準(zhǔn)備工作

  • 在spring配置文件中引入context文件

    xmlns:context="http://www.springframework.org/schema/context"
    
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context.xsd
    
  • 開啟屬性注解支持添诉!

    <context:annotation-config/>
    
  • 匯總

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:context="http://www.springframework.org/schema/context"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            https://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/context
            https://www.springframework.org/schema/context/spring-context.xsd">
    
        <context:annotation-config/>
    
    </beans>
    

@Autowired

  • @Autowired是按類型自動(dòng)轉(zhuǎn)配的,不支持id匹配医寿。
  • 需要導(dǎo)入 spring-aop的包栏赴!

測試:

1、將User類中的set方法去掉靖秩,使用@Autowired注解

public class User {
   @Autowired
   private Cat cat;
   @Autowired
   private Dog dog;
   private String str;

   public Cat getCat() {
       return cat;
  }
   public Dog getDog() {
       return dog;
  }
   public String getStr() {
       return str;
  }

2艾帐、此時(shí)配置文件內(nèi)容

<context:annotation-config/>

<bean id="dog" class="com.nie.pojo.Dog"/>
<bean id="cat" class="com.nie.pojo.Cat"/>
<bean id="user" class="com.nie.pojo.User"/>

3、測試盆偿,成功輸出結(jié)果!

@Autowired(required=false) 說明:false准浴,對象可以為null事扭;true,對象必須存對象乐横,不能為null求橄。

//如果允許對象為null今野,設(shè)置required = false,默認(rèn)為true
@Autowired(required = false)
private Cat cat;

@Qualifier

  • @Autowired是根據(jù)類型自動(dòng)裝配的,加上@Qualifier則可以根據(jù)byName的方式自動(dòng)裝配
  • @Qualifier不能單獨(dú)使用罐农。

測試實(shí)驗(yàn)步驟:

1条霜、配置文件修改內(nèi)容,保證類型存在對象涵亏。且名字不為類的默認(rèn)名字宰睡!

<bean id="dog1" class="com.nie.pojo.Dog"/>
<bean id="dog2" class="com.nie.pojo.Dog"/>
<bean id="cat1" class="com.nie.pojo.Cat"/>
<bean id="cat2" class="com.nie.pojo.Cat"/>

2、沒有加Qualifier測試气筋,直接報(bào)錯(cuò)

3拆内、在屬性上添加Qualifier注解

@Autowired
@Qualifier(value = "cat2")
private Cat cat;
@Autowired
@Qualifier(value = "dog2")
private Dog dog;

測試,成功輸出宠默!

@Resource

  • @Resource如有指定的name屬性麸恍,先按該屬性進(jìn)行byName方式查找裝配;
  • 其次再進(jìn)行默認(rèn)的byName方式進(jìn)行裝配搀矫;
  • 如果以上都不成功抹沪,則按byType的方式自動(dòng)裝配。
  • 都不成功瓤球,則報(bào)異常融欧。

實(shí)體類:

public class User {
   //如果允許對象為null,設(shè)置required = false,默認(rèn)為true
   @Resource(name = "cat2")
   private Cat cat;
   @Resource
   private Dog dog;
   private String str;
}

beans.xml

<bean id="dog" class="com.nie.pojo.Dog"/>
<bean id="cat1" class="com.nie.pojo.Cat"/>
<bean id="cat2" class="com.nie.pojo.Cat"/>

<bean id="user" class="com.nie.pojo.User"/>

測試:結(jié)果OK

配置文件2:beans.xml 冰垄, 刪掉cat2

<bean id="dog" class="com.nie.pojo.Dog"/>
<bean id="cat1" class="com.nie.pojo.Cat"/>

實(shí)體類上只保留注解

@Resource
private Cat cat;
@Resource
private Dog dog;

結(jié)果:OK

結(jié)論:先進(jìn)行byName查找蹬癌,失敗虹茶;再進(jìn)行byType查找逝薪,成功。

小結(jié)

@Autowired與@Resource異同:

1蝴罪、@Autowired與@Resource都可以用來裝配bean董济。都可以寫在字段上,或?qū)懺趕etter方法上要门。

2虏肾、@Autowired默認(rèn)按類型裝配(屬于spring規(guī)范),默認(rèn)情況下必須要求依賴對象必須存在欢搜,如果要允許null 值封豪,可以設(shè)置它的required屬性為false,如:@Autowired(required=false) 炒瘟,如果我們想使用名稱裝配可以結(jié)合@Qualifier注解進(jìn)行使用

3吹埠、@Resource(屬于J2EE復(fù)返),默認(rèn)按照名稱進(jìn)行裝配,名稱可以通過name屬性進(jìn)行指定缘琅。如果沒有指定name屬性粘都,當(dāng)注解寫在字段上時(shí),默認(rèn)取字段名進(jìn)行按照名稱查找刷袍,如果注解寫在setter方法上默認(rèn)取屬性名進(jìn)行裝配翩隧。當(dāng)找不到與名稱匹配的bean時(shí)才按照類型進(jìn)行裝配。但是需要注意的是呻纹,如果name屬性一旦指定堆生,就只會(huì)按照名稱進(jìn)行裝配。

它們的作用相同都是用注解方式注入對象居暖,但執(zhí)行順序不同顽频。@Autowired先byType,@Resource先byName太闺。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末糯景,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子省骂,更是在濱河造成了極大的恐慌蟀淮,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件钞澳,死亡現(xiàn)場離奇詭異怠惶,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)轧粟,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門策治,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人兰吟,你說我怎么就攤上這事通惫。” “怎么了混蔼?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵履腋,是天一觀的道長。 經(jīng)常有香客問我惭嚣,道長遵湖,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任晚吞,我火速辦了婚禮延旧,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘槽地。我一直安慰自己垄潮,他們只是感情好烹卒,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著弯洗,像睡著了一般。 火紅的嫁衣襯著肌膚如雪逢勾。 梳的紋絲不亂的頭發(fā)上牡整,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音溺拱,去河邊找鬼逃贝。 笑死,一個(gè)胖子當(dāng)著我的面吹牛迫摔,可吹牛的內(nèi)容都是我干的沐扳。 我是一名探鬼主播,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼句占,長吁一口氣:“原來是場噩夢啊……” “哼沪摄!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起纱烘,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬榮一對情侶失蹤杨拐,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后擂啥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體哄陶,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年哺壶,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了屋吨。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡山宾,死狀恐怖至扰,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情塌碌,我是刑警寧澤渊胸,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布,位于F島的核電站台妆,受9級(jí)特大地震影響翎猛,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜接剩,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一切厘、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧懊缺,春花似錦疫稿、人聲如沸培他。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽舀凛。三九已至,卻和暖如春途蒋,著一層夾襖步出監(jiān)牢的瞬間猛遍,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來泰國打工号坡, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留懊烤,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓宽堆,卻偏偏與公主長得像腌紧,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子畜隶,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

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