今天和同事討論到Spring自動注入時,發現有這么一段代碼特別地困惑,當然大致的原理還是可以理解的,只不過以前從來沒有這么用過。想到未來可能會用到,或者未來看別人寫的代碼時不至于花時間解決同樣的困惑,所以小編還是覺得有必要研究記錄一下。
一、同一類型注入多次為同一實例
首先讓我們先看下這段代碼是什么?
@Autowiredprivate XiaoMing xiaoming;@Autowiredprivate 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$ * */@Servicepublic class XiaoMing { public void printName() { System.err.println("小明"); }}
我們都知道 @Autowired
可以根據類型( Type
)進行自動注入,并且默認注入的bean為單例( SingleTon
)的,那么我們可能會問,上面注入兩次不會重復嗎?答案是肯定的。而且每次注入的實例都是同一個實例。下面我們簡單驗證下:
@RestControllerpublic 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"; }}
調用上面的接口之后,將輸出下面內容,可以看出兩者為同一實例。
com.example.demo.beans.impl.XiaoMing@6afd4ce9
com.example.demo.beans.impl.XiaoMing@6afd4ce9
二、注入接口類型實例
如果我們要注入的類型聲明為一個接口類型,而且該接口有1個以上的實現類,那么下面這段代碼還能夠正常運行嗎?我們假設 Student
為接口, WangEr
和 XiaoMing
為兩個實現類。
@Autowiredprivate Student stu1;@Autowiredprivate Student stu2;
@Servicepublic class XiaoMing implements Student {
@Servicepublic class WangEr implements Student {
答案是上面的代碼不能正常運行,而且Spring 還啟動報錯了,原因是Spring想為 Student 注入一個單例的實例,但在注入的過程中意外地發現兩個,所以報錯,具體錯誤信息如下:
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]
那該怎么弄才行呢?一般思路我們會想到為每個實現類分配一個id值,結果就有了下面的代碼:
@Autowiredprivate Student stu1;@Autowiredprivate Student stu2;
@Service("stu1")public class XiaoMing implements Student {
@Service("stu2")public class WangEr implements Student {
做完上面的配置之后,Spring就會根據字段名稱默認去bean工廠找相應的bean進行注入,注意名稱不能夠隨便取的,要和注入的屬性名一致。
三、總結
@Autowired
注入多次,并且所有注入的實例都是同一個實例;以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持VeVb武林網。
新聞熱點
疑難解答
圖片精選