詳解Spring @Autowired 注入小技巧
今天和同事討論到Spring自動(dòng)注入時(shí),發(fā)現(xiàn)有這么一段代碼特別地困惑,當(dāng)然大致的原理還是可以理解的,只不過(guò)以前從來(lái)沒(méi)有這么用過(guò)。想到未來(lái)可能會(huì)用到,或者未來(lái)看別人寫的代碼時(shí)不至于花時(shí)間解決同樣的困惑,所以小編還是覺(jué)得有必要研究記錄一下。
一、同一類型注入多次為同一實(shí)例
首先讓我們先看下這段代碼是什么?
@Autowired private XiaoMing xiaoming; @Autowired private XiaoMing wanger;
XiaoMing.java
package com.example.demo.beans.impl;
import org.springframework.stereotype.Service;
/**
*
* The class XiaoMing.
*
* Description:小明
*
* @author: huangjiawei
* @since: 2018年7月23日
* @version: $Revision$ $Date$ $LastChangedBy$
*
*/
@Service
public class XiaoMing {
public void printName() {
System.err.println("小明");
}
}
我們都知道 @Autowired 可以根據(jù)類型( Type )進(jìn)行自動(dòng)注入,并且默認(rèn)注入的bean為單例( SingleTon )的,那么我們可能會(huì)問(wèn),上面注入兩次不會(huì)重復(fù)嗎?答案是肯定的。而且每次注入的實(shí)例都是同一個(gè)實(shí)例。下面我們簡(jiǎn)單驗(yàn)證下:
@RestController
public class MyController {
@Autowired
private XiaoMing xiaoming;
@Autowired
private XiaoMing wanger;
@RequestMapping(value = "/test.json", method = RequestMethod.GET)
public String test() {
System.err.println(xiaoming);
System.err.println(wanger);
return "hello";
}
}
調(diào)用上面的接口之后,將輸出下面內(nèi)容,可以看出兩者為同一實(shí)例。
com.example.demo.beans.impl.XiaoMing@6afd4ce9
com.example.demo.beans.impl.XiaoMing@6afd4ce9
二、注入接口類型實(shí)例
如果我們要注入的類型聲明為一個(gè)接口類型,而且該接口有1個(gè)以上的實(shí)現(xiàn)類,那么下面這段代碼還能夠正常運(yùn)行嗎?我們假設(shè) Student 為接口, WangEr 和 XiaoMing 為兩個(gè)實(shí)現(xiàn)類。
@Autowired private Student stu1; @Autowired private Student stu2;
@Service
public class XiaoMing implements Student {
@Service
public class WangEr implements Student {
答案是上面的代碼不能正常運(yùn)行,而且Spring 還啟動(dòng)報(bào)錯(cuò)了,原因是Spring想為 Student 注入一個(gè)單例的實(shí)例,但在注入的過(guò)程中意外地發(fā)現(xiàn)兩個(gè),所以報(bào)錯(cuò),具體錯(cuò)誤信息如下:
Field stu1 in com.example.demo.controller.MyController required a single bean, but 2 were found:
- wangEr: defined in file [C:\Users\huangjiawei\Desktop\demo\target\classes\com\example\demo\beans\impl\WangEr.class]
- xiaoMing: defined in file [C:\Users\huangjiawei\Desktop\demo\target\classes\com\example\demo\beans\impl\XiaoMing.class]
那該怎么弄才行呢?一般思路我們會(huì)想到為每個(gè)實(shí)現(xiàn)類分配一個(gè)id值,結(jié)果就有了下面的代碼:
@Autowired private Student stu1; @Autowired private Student stu2;
@Service("stu1")
public class XiaoMing implements Student {
@Service("stu2")
public class WangEr implements Student {
做完上面的配置之后,Spring就會(huì)根據(jù)字段名稱默認(rèn)去bean工廠找相應(yīng)的bean進(jìn)行注入,注意名稱不能夠隨便取的,要和注入的屬性名一致。
三、總結(jié)
- 1、同一類型可以使用
@Autowired注入多次,并且所有注入的實(shí)例都是同一個(gè)實(shí)例; - 2、當(dāng)對(duì)接口進(jìn)行注入時(shí),應(yīng)該為每個(gè)實(shí)現(xiàn)類指明相應(yīng)的id,則Spring將報(bào)錯(cuò);
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
解決redisTemplate中l(wèi)eftPushAll隱性bug的問(wèn)題
這篇文章主要介紹了解決redisTemplate中l(wèi)eftPushAll隱性bug的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2021-02-02
java 集合并發(fā)操作出現(xiàn)的異常ConcurrentModificationException
Map在遍歷時(shí)候通常 現(xiàn)獲得其鍵值的集合Set,然后用迭代器Iterator來(lái)對(duì)Map進(jìn)行遍歷。2009-06-06
Java數(shù)據(jù)庫(kù)連接_jdbc-odbc橋連接方式(詳解)
下面小編就為大家?guī)?lái)一篇Java數(shù)據(jù)庫(kù)連接_jdbc-odbc橋連接方式(詳解)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-08-08
java使用@Transactional時(shí)常犯的N種錯(cuò)誤
@Transactional是我們?cè)谟肧pring時(shí)候幾乎逃不掉的一個(gè)注解,本文主要介紹了使用?@Transactional?時(shí)常犯的N種錯(cuò)誤,文中通過(guò)示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2022-01-01
java編程實(shí)現(xiàn)楊輝三角兩種輸出結(jié)果實(shí)例代碼
這篇文章主要介紹了java編程實(shí)現(xiàn)楊輝三角兩種輸出結(jié)果實(shí)例代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12
Spring?Cloud負(fù)載均衡組件Ribbon原理解析
本文主要講述了微服務(wù)體系下的?Spring?Cloud?Netflix?套件中?Ribbon?的使用,并結(jié)合部分源碼講述了?Ribbon?的底層原理,重點(diǎn)講述了?Ribbon?中是如何獲取服務(wù)以及如何判定一個(gè)服務(wù)是否可用,最后也介紹了?Ribbon?中默認(rèn)提供的?7?種負(fù)載均衡策略,感興趣的朋友一起看看吧2022-04-04
Java多線程 BlockingQueue實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型詳解
這篇文章主要介紹了Java多線程 BlockingQueue實(shí)現(xiàn)生產(chǎn)者消費(fèi)者模型詳解,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-09-09
Java實(shí)現(xiàn)的動(dòng)態(tài)數(shù)字時(shí)鐘功能示例【顯示世界時(shí)間】
這篇文章主要介紹了Java實(shí)現(xiàn)的動(dòng)態(tài)數(shù)字時(shí)鐘功能,結(jié)合實(shí)例形式分析了java顯示北京、紐約、倫敦等世界時(shí)間的相關(guān)日期時(shí)間運(yùn)算操作技巧,需要的朋友可以參考下2019-03-03

