您好,登錄后才能下訂單哦!
這篇文章主要講解了“Spring注入Bean方式是什么”,文中的講解內(nèi)容簡(jiǎn)單清晰,易于學(xué)習(xí)與理解,下面請(qǐng)大家跟著小編的思路慢慢深入,一起來(lái)研究和學(xué)習(xí)“Spring注入Bean方式是什么”吧!
Spring框架的核心功能之一就是通過(guò)依賴(lài)注入的方式來(lái)管理Bean之間的依賴(lài)關(guān)系。
每個(gè)基于應(yīng)用程序的 java 都有幾個(gè)對(duì)象,由這些對(duì)象一起工作來(lái)呈現(xiàn)出終端用戶(hù)所看到的工作的應(yīng)用程序。當(dāng)編寫(xiě)一個(gè)復(fù)雜的 Java 應(yīng)用程序時(shí),應(yīng)用程序類(lèi)應(yīng)該盡可能獨(dú)立于其他 Java 類(lèi)來(lái)增加這些類(lèi)重用的可能性,并且在做單元測(cè)試時(shí),測(cè)試獨(dú)立于其他類(lèi)的獨(dú)立性。依賴(lài)注入(或有時(shí)稱(chēng)為布線(xiàn))
有助于把這些類(lèi)粘合在一起,同時(shí)保持他們獨(dú)立。
Spring通過(guò)DI(依賴(lài)注入)實(shí)現(xiàn)IOC(控制反轉(zhuǎn)),常用的注入方式主要有三種:
構(gòu)造方法注入
setter注入
基于注解的注入
<!-- 注冊(cè)u(píng)serService --> <bean id="userService">
問(wèn)題一:如果有多個(gè)有參數(shù)的構(gòu)造方法并且每個(gè)構(gòu)造方法的參數(shù)列表里面都有要注入的屬性,那userDaoJdbc會(huì)注入到哪里呢?
public class UserService implements IUserService { private IUserDao userDao; private User user; public UserService(IUserDao userDao) { System.out.println("這是有一個(gè)參數(shù)的構(gòu)造方法"); this.userDao = userDao; } public UserService(IUserDao userDao, User user) { System.out.println("這是有兩個(gè)參數(shù)的構(gòu)造方法"); this.userDao = userDao; this.user = user; } public void loginUser() { userDao.loginUser(); } } 結(jié)果:會(huì)注入到只有一個(gè)參數(shù)的構(gòu)造方法中,并且經(jīng)過(guò)測(cè)試注入哪一個(gè)構(gòu)造方法與構(gòu)造方法的順序無(wú)關(guān)
問(wèn)題二:如果只有一個(gè)構(gòu)造方法,但是有兩個(gè)參數(shù),一個(gè)是待注入的參數(shù),另一個(gè)是其他類(lèi)型的參數(shù),那么這次注入可以成功嗎?
public class UserService implements IUserService { private IUserDao userDao; private User user; public UserService(IUserDao userDao, User user) { this.userDao = userDao; this.user = user; } public void loginUser() { userDao.loginUser(); } } 結(jié)果:失敗了,即使在costract-arg標(biāo)簽里面通過(guò)name屬性指定要注入的參數(shù)名userDao也會(huì)失敗.
問(wèn)題三:如果我們想向有多個(gè)參數(shù)的構(gòu)造方法中注入值該在配置文件中怎么寫(xiě)呢?
public class UserService implements IUserService { private IUserDao userDao; private User user; public UserService(IUserDao userDao, User user) { this.userDao = userDao; this.user = user; } public void loginUser() { userDao.loginUser(); } } 參考寫(xiě)法:通過(guò)name屬性指定要注入的值,與構(gòu)造方法參數(shù)列表參數(shù)的順序無(wú)關(guān)。 <!-- 注冊(cè)u(píng)serService --> <bean id="userService" class="com.spring.service.impl.UserService"> <constructor-arg name="userDao" ref="userDaoJdbc"></constructor-arg> <constructor-arg name="user" ref="user"></constructor-arg> </bean> <!-- 注冊(cè)實(shí)體User類(lèi),用于測(cè)試 --> <bean id="user" class="com.spring.entity.User"></bean> <!-- 注冊(cè)jdbc實(shí)現(xiàn)的dao --> <bean id="userDaoJdbc" class="com.spring.dao.impl.UserDaoJdbc"></bean>
問(wèn)題四:如果有多個(gè)構(gòu)造方法,每個(gè)構(gòu)造方法只有參數(shù)的順序不同,那通過(guò)構(gòu)造方法注入多個(gè)參數(shù)會(huì)注入到哪一個(gè)呢?
public class UserService implements IUserService { private IUserDao userDao; private User user; public UserService(IUserDao userDao, User user) { System.out.println("這是第二個(gè)構(gòu)造方法"); this.userDao = userDao; this.user = user; } public UserService(User user, IUserDao userDao) { System.out.println("這是第一個(gè)構(gòu)造方法"); this.userDao = userDao; this.user = user; } public void loginUser() { userDao.loginUser(); } } 結(jié)果:哪個(gè)構(gòu)造方法在前就注入哪一個(gè),這種情況下就與構(gòu)造方法順序有關(guān)。
<!-- 注冊(cè)u(píng)serService --> <bean id="userService" class="com.spring.service.impl.UserService"> <!-- 寫(xiě)法一 --> <!-- <property name="UserDao" ref="userDaoMyBatis"></property> --> <!-- 寫(xiě)法二 --> <property name="userDao" ref="userDaoMyBatis"></property> </bean> <!-- 注冊(cè)mybatis實(shí)現(xiàn)的dao --> <bean id="userDaoMyBatis" class="com.spring.dao.impl.UserDaoMyBatis"></bean> 注:上面這兩種寫(xiě)法都可以。spring會(huì)將name值的每個(gè)單詞首字母轉(zhuǎn)換成大寫(xiě),然后再在前面拼接上"set"構(gòu)成一個(gè)方法名,然后去對(duì)應(yīng)的類(lèi)中查找該方法,通過(guò)反射調(diào)用,實(shí)現(xiàn)注入。
public class UserService implements IUserService { private IUserDao userDao1; public void setUserDao(IUserDao userDao1) { this.userDao1 = userDao1; } public void loginUser() { userDao1.loginUser(); } } 注意:如果通過(guò)set方法注入屬性,那么spring會(huì)通過(guò)默認(rèn)的空參構(gòu)造方法來(lái)實(shí)例化對(duì)象,所以如果在類(lèi)中寫(xiě)了一個(gè)帶有參數(shù)的構(gòu)造方法,一定要把空參數(shù)的構(gòu)造方法寫(xiě)上,否則spring沒(méi)有辦法實(shí)例化對(duì)象,導(dǎo)致報(bào)錯(cuò)。
在介紹注解注入的方式前,先簡(jiǎn)單了解bean的一個(gè)屬性autowire,autowire主要有三個(gè)屬性值:constructor,byName,byType。
constructor:通過(guò)構(gòu)造方法進(jìn)行自動(dòng)注入,spring會(huì)匹配與構(gòu)造方法參數(shù)類(lèi)型一致的bean進(jìn)行注入,如果有一個(gè)多參數(shù)的構(gòu)造方法,一個(gè)只有一個(gè)參數(shù)的構(gòu)造方法,在容器中查找到多個(gè)匹配多參數(shù)構(gòu)造方法的bean,那么spring會(huì)優(yōu)先將bean注入到多參數(shù)的構(gòu)造方法中。
byName:被注入bean的id名必須與set方法后半截匹配,并且id名稱(chēng)的第一個(gè)單詞首字母必須小寫(xiě),這一點(diǎn)與手動(dòng)set注入有點(diǎn)不同。
byType:查找所有的set方法,將符合符合參數(shù)類(lèi)型的bean注入。
主要有四種注解可以注冊(cè)bean,每種注解可以任意使用,只是語(yǔ)義上有所差異:
@Component:可以用于注冊(cè)所有bean
@Repository:主要用于注冊(cè)dao層的bean
@Controller:主要用于注冊(cè)控制層的bean
@Service:主要用于注冊(cè)服務(wù)層的bean
描述依賴(lài)關(guān)系主要有兩種:
@Resource:java的注解,默認(rèn)以byName的方式去匹配與屬性名相同的bean的id,如果沒(méi)有找到,就會(huì)以byType的方式查找,如果byType查找到多個(gè)的話(huà),使用@Qualifier注解(spring注解)指定某個(gè)具體名稱(chēng)的bean。
@Resource @Qualifier("userDaoMyBatis") private IUserDao userDao; public UserService(){ }
@Autowired:spring注解,默認(rèn)是以byType的方式去匹配類(lèi)型相同的bean,如果只匹配到一個(gè),那么就直接注入該bean,無(wú)論要注入的 bean 的 name 是什么;如果匹配到多個(gè)就會(huì)調(diào)用 DefaultListableBeanFactory 的 determineAutowireCandidate 方法來(lái)決定具體注入哪個(gè)bean。determineAutowireCandidate 方法的內(nèi)容如下:
@Autowired @Qualifier("userDaoJdbc") private IUserDao userDao; 可以簡(jiǎn)單的理解為先以 ByType 的方式去匹配,如果匹配到了多個(gè)再以 ByName 的方式去匹配,找到了對(duì)應(yīng)的 bean 就去注入,沒(méi)找到就拋出異常。
感謝各位的閱讀,以上就是“Spring注入Bean方式是什么”的內(nèi)容了,經(jīng)過(guò)本文的學(xué)習(xí)后,相信大家對(duì)Spring注入Bean方式是什么這一問(wèn)題有了更深刻的體會(huì),具體使用情況還需要大家實(shí)踐驗(yàn)證。這里是億速云,小編將為大家推送更多相關(guān)知識(shí)點(diǎn)的文章,歡迎關(guān)注!
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。