Spring @Autowired 注入小技巧

今天和同事討論到Spring自動注入時,發現有這麼一段代碼特別地困惑,固然大體的原理仍是能夠理解的,只不過之前歷來沒有這麼用過。想到將來可能會用到,或者將來看別人寫的代碼時不至於花時間解決一樣的困惑,因此小編仍是以爲有必要研究記錄一下。java

1、同一類型注入屢次爲同一實例

首先讓咱們先看下這段代碼是什麼?spring

@Autowired
private XiaoMing xiaoming;

@Autowired
private XiaoMing wanger;
複製代碼

XiaoMing.javajson

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能夠根據類型(Type)進行自動注入,而且默認注入的bean爲單例(SingleTon)的,那麼咱們可能會問,上面注入兩次不會重複嗎?答案是確定的。並且每次注入的實例都是同一個實例。下面咱們簡單驗證下:bash

@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";
    }
}
複製代碼

調用上面的接口以後,將輸出下面內容,能夠看出二者爲同一實例。app

com.example.demo.beans.impl.XiaoMing@6afd4ce9
com.example.demo.beans.impl.XiaoMing@6afd4ce9
複製代碼

2、注入接口類型實例

若是咱們要注入的類型聲明爲一個接口類型,並且該接口有1個以上的實現類,那麼下面這段代碼還可以正常運行嗎?咱們假設Student爲接口,WangErXiaoMing爲兩個實現類。ui

@Autowired
private Student stu1;

@Autowired
private Student stu2;
複製代碼
@Service
public class XiaoMing implements Student {
複製代碼
@Service
public class WangEr implements Student {
複製代碼

答案是上面的代碼不能正常運行,並且Spring 還啓動報錯了,緣由是Spring想爲Student注入一個單例的實例,但在注入的過程當中意外地發現兩個,因此報錯,具體錯誤信息以下:spa

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值,結果就有了下面的代碼:code

@Autowired
private Student stu1;

@Autowired
private Student stu2;
複製代碼
@Service("stu1")
public class XiaoMing implements Student {
複製代碼
@Service("stu2")
public class WangEr implements Student {
複製代碼

作完上面的配置以後,Spring就會根據字段名稱默認去bean工廠找相應的bean進行注入,注意名稱不可以隨便取的,要和注入的屬性名一致。接口

3、總結

  • 一、同一類型可使用@Autowired注入屢次,而且全部注入的實例都是同一個實例;
  • 二、當對接口進行注入時,應該爲每一個實現類指明相應的id,則Spring將報錯;
相關文章
相關標籤/搜索