Spring中byName和byType的區(qū)別及說明
測(cè)試實(shí)例
Cat類:
public class Cat { public void sound(){ System.out.println("miao~"); } }
Dog類:
public class Dog { public void sound(){ System.out.println("wang~"); } }
People類:
public class People { private Cat cat; private Dog dog; private String name; public Cat getCat(){ return cat; } public void setCat(Cat cat) { this.cat = cat; } public Dog getDog(){ return dog; } public void setDog(Dog dog) { this.dog = dog; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
xml配置文件:
<?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 http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <bean id = "cat" class="com.hello.pojo.Cat"/> <bean id = "dog" class="com.hello.pojo.Dog"/> <bean id = "people" class="com.hello.pojo.People"> <property name="cat" ref="cat"/> <property name="dog" ref="dog"/> <property name="name" value="wzh"/> </bean> </beans>
輸出:
一、在配置文件中裝配bean
(一)byName
byName就是通過Bean的屬性名稱(id或name)自動(dòng)裝配。
實(shí)例:
1、修改xml配置,增加一個(gè)屬性 autowire="byName":
<bean id = "cat" class="com.hello.pojo.Cat"/> <bean id = "dog" class="com.hello.pojo.Dog"/> <bean id = "people" class="com.hello.pojo.People" autowire="byName"> <property name="name" value="wzh"/> </bean>
此時(shí)測(cè)試成功
2、我們將 cat 的bean id修改為 catXXX
<bean id = "cat2" class="com.hello.pojo.Cat"/>
出現(xiàn)錯(cuò)誤如下:
執(zhí)行時(shí)報(bào)空指針java.lang.NullPointerException。因?yàn)榘碽yName規(guī)則找不對(duì)應(yīng)set方法,真正的setCat就沒執(zhí)行,對(duì)象就沒有初始化,所以調(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的對(duì)象。
(3)如果有,就取出注入;如果沒有,就報(bào)空指針異常。
(二)byType
byName就是通過Bean的Class類型來自動(dòng)裝配。使用autowire byType首先需要保證:同一類型的對(duì)象,在spring容器中唯一。如果不唯一,會(huì)報(bào)不唯一的異常。
實(shí)例:
在xml配置再注冊(cè)一個(gè)cat的bean對(duì)象:
<bean id = "cat" class="com.hello.pojo.Cat"/> <bean id = "cat2" class="com.hello.pojo.Cat"/> <bean id = "dog" class="com.hello.pojo.Dog"/> <bean id = "people" class="com.hello.pojo.People" autowire="byType"> <!-- <property name="cat" ref="cat"/>--> <!-- <property name="dog" ref="dog"/>--> <property name="name" value="wzh"/> </bean>
測(cè)試結(jié)果:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'people' defined in class path resource [beans.xml]: Unsatisfied dependency expressed through bean property 'cat'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.hello.pojo.Cat' available: expected single matching bean but found 2: cat,cat2
“NoUniqueBeanDefinitionException”,即bean定義不唯一。刪掉其中一個(gè)cat的bean對(duì)象,將cat的bean名稱改掉,則可測(cè)試成功,因?yàn)槭前搭愋脱b配,所以并不會(huì)報(bào)異常,也不影響最后的結(jié)果。甚至將id屬性去掉,也不影響結(jié)果。
二、使用注解實(shí)現(xiàn)自動(dòng)裝配
0、使用注解實(shí)現(xiàn)自動(dòng)裝配需要在xml配置文件中添加以下2個(gè)支持:
(1)在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
(2)開啟屬性注解支持!
<context:annotation-config/>
(一)@Autowired
- @Autowired是按類型自動(dòng)轉(zhuǎn)配的,不支持id匹配。
- 需要導(dǎo)入 spring-aop的包!
1、測(cè)試
(1)將People類中的set方法去掉,使用@Autowired注解
public class People { @Autowired private Cat cat; @Autowired private Dog dog; private String name; public Cat getCat(){ return cat; } public Dog getDog(){ return dog; } public String getName() { return name; } }
此時(shí)ml配置文件:
<context:annotation-config/> <bean id = "cat" class="com.hello.pojo.Cat"/> <bean id = "dog" class="com.hello.pojo.Dog"/> <bean id = "people" class="com.hello.pojo.People"> </bean>
測(cè)試結(jié)果:
注:@Autowired(required=false) 說明對(duì)象可以為null;如果required=false,則對(duì)象必須存對(duì)象,不能為null。
(二)Qualifier
- @Autowired是根據(jù)類型自動(dòng)裝配的,加上@Qualifier則可以根據(jù)byName的方式自動(dòng)裝配。
- @Qualifier不能單獨(dú)使用。
測(cè)試:
(1)配置文件修改內(nèi)容,保證類型存在對(duì)象。且名字不為類的默認(rèn)名字。
<bean id = "cat1" class="com.hello.pojo.Cat"/> <bean id = "cat2" class="com.hello.pojo.Cat"/> <bean id = "dog1" class="com.hello.pojo.Dog"/> <bean id = "dog2" class="com.hello.pojo.Dog"/>
此時(shí)報(bào)錯(cuò):
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'people': Unsatisfied dependency expressed through field 'cat'; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.hello.pojo.Cat' available: expected single matching bean but found 2: cat1,cat2
(2)在屬性上添加Qualifier注解
@Autowired @Qualifier(value = "cat2") private Cat cat; @Autowired @Qualifier(value = "dog2") private Dog dog;
測(cè)試測(cè)試成功。
(三)@Resource
- @Resource如有指定的name屬性,先按該屬性進(jìn)行byName方式查找裝配;
- 其次再進(jìn)行默認(rèn)的byName方式進(jìn)行裝配;
- 如果以上都不成功,則按byType的方式自動(dòng)裝配。
- 都不成功,則報(bào)異常。
測(cè)試:
public class People { @Resource(name = "cat2") private Cat cat; @Resource(name = "dog2") private Dog dog; private String name; public Cat getCat(){ return cat; } public Dog getDog(){ return dog; } public String getName() { return name; } }
此時(shí)xml配置文件:
<bean id = "cat1" class="com.hello.pojo.Cat"/> <bean id = "cat2" class="com.hello.pojo.Cat"/> <bean id = "dog1" class="com.hello.pojo.Dog"/> <bean id = "dog2" class="com.hello.pojo.Dog"/>
(2)實(shí)體類和xml配置文件:
public class People { @Resource private Cat cat; @Resource private Dog dog; private String name; public Cat getCat(){ return cat; } public Dog getDog(){ return dog; } public String getName() { return name; } }
配置文件:
<bean id = "cat1" class="com.hello.pojo.Cat"/> <bean id = "dog1" class="com.hello.pojo.Dog"/>
測(cè)試結(jié)果成功輸出。
結(jié)論:
@Resource先進(jìn)行byName查找,失??;再進(jìn)行byType查找,成功。
小結(jié):
@Autowired與@Resource異同
- @Autowired與@Resource都可以用來裝配bean。都可以寫在字段上,或?qū)懺趕etter方法上。
- @Autowired默認(rèn)按類型裝配(屬于spring規(guī)范),默認(rèn)情況下必須要求依賴對(duì)象必須存在,如果要允許null 值,可以設(shè)置它的required屬性為false,如:@Autowired(required=false) ,如果我們想使用名稱裝配可以結(jié)合@Qualifier注解進(jìn)行使用
- @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)行裝配。
- 它們的作用相同都是用注解方式注入對(duì)象,但執(zhí)行順序不同。@Autowired先byType,@Resource先byName。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
java基礎(chǔ)詳解之?dāng)?shù)據(jù)類型知識(shí)點(diǎn)總結(jié)
這篇文章主要介紹了java基礎(chǔ)詳解之?dāng)?shù)據(jù)類型知識(shí)點(diǎn)總結(jié),文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java基礎(chǔ)的小伙伴們有很大的幫助,需要的朋友可以參考下2021-04-04解決Mybatis-Plus更新方法不更新NULL字段的問題
這篇文章主要介紹了解決Mybatis-Plus更新方法不更新NULL字段的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-12-12Nacos?版本不一致報(bào)錯(cuò)Request?nacos?server?failed解決
這篇文章主要為大家介紹了Nacos?版本不一致報(bào)錯(cuò)Request?nacos?server?failed的解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11分布式調(diào)度XXL-Job整合Springboot2.X實(shí)戰(zhàn)操作過程(推薦)
這篇文章主要介紹了分布式調(diào)度XXL-Job整合Springboot2.X實(shí)戰(zhàn)操作,包括定時(shí)任務(wù)的使用場(chǎng)景和常見的定時(shí)任務(wù),通過本文學(xué)習(xí)幫助大家該選擇哪個(gè)分布式任務(wù)調(diào)度平臺(tái),對(duì)此文感興趣的朋友一起看看吧2022-04-04深入解析Spring Bean初始化時(shí)和銷毀時(shí)的擴(kuò)展點(diǎn)
在Bean進(jìn)行初始化或者銷毀的時(shí)候,如果我們需要做一些操作,比如加載和銷毀一些資源或者執(zhí)行一些方法時(shí),那么就可以使用Spring提供的一些擴(kuò)展,今天主要分享初始化Bean時(shí)的三種方式和銷毀Bean時(shí)的三種方式,需要的朋友可以參考下2023-08-08mybatis中resultMap 標(biāo)簽的使用教程
resultMap 標(biāo)簽用來描述如何從數(shù)據(jù)庫結(jié)果集中來加載對(duì)象,這篇文章重點(diǎn)給大家介紹mybatis中resultMap 標(biāo)簽的使用,感興趣的朋友一起看看吧2018-07-07深入了解Maven Settings.xml文件的結(jié)構(gòu)和功能
這篇文章主要為大家介紹了Maven Settings.xml文件基本結(jié)構(gòu)和功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11