@Autowired, @Qualifier
@Autowired
通常是加在class變數上
根據變數的類型 ,去 Spring 容器中尋找有沒有符合類型的 bean
public class Teacher{
// step3 :printer 變數的類型盡量使用"interface" ,在這邊是用 Printer
// 因為@Autowired 是根據變數的類型去Spring 容器中尋找有沒有符合類型的bean
@Autowired
private Printer printer; // step2: 所以類型符合 ,依賴注入成功
public void teach(){
printer.print("I'm a teacher!");
}
}
Printer hpPrinter = new HpPrinter(); // step1: hpPrinter可以向上轉型成Printer
目的: 讓其關聯性降低
通常步驟:
- 創建一個 interface
- 接著寫一個 class 去實現這個 interface
- 如果要改換 class ,完全不需要修改 Teacher 的內容
如果同時有兩個class 同時去實現了Printer ,那@Autowired 它到底是要講哪一個bean交給 Teacher???
@Qualifier
通常是加在 class 變數上 ,會跟 @Autowired 一起用
指定要載入的bean名字
public class Teacher{
@Autowired
@Qualifier("hpPrinter") // 指定要載入的bean的名字
private Printer printer;
public void teach(){
printer.print("I'm a teacher!");
}
}
// Bean hpPrinter
@Component
public class HpPrinter implements Printer{
}
// Bean canonPrinter
@Component
public class CanonPrinter implements Printer{
}
- 當 Spring 創建 bean 的時候 ,bean 的名字會是 classname 第一個字母會轉成小寫
註解沒有順序性
public class Teacher{
@Autowired
@Qualifier("hpPrinter")
private Printer printer;
public void teach(){
printer.print("I'm a teacher!");
}
}
// 或是寫這樣也可以
public class Teacher{
@Qualifier("hpPrinter")
@Autowired
private Printer printer;
public void teach(){
printer.print("I'm a teacher!");
}
}
練習
建立一個Printer介面
兩個不同的印表機去實作這個 interface

接著切回 main 方法執行
在網址上輸入 localhost:8080/test (因為@RequestMapping("/test"))
因為我們加上 @Qualifier 指定要注入的 bean 是”canonPrinter “

所以 console 打印的是 canon 的印表機
console:
如果沒有加上 @Qualifier 指定是哪個 bean 的話
***************************
APPLICATION FAILED TO START
***************************
Description:
Field printer in com.example.demo.MyController required a single bean, but 2 were found:
- canonPrinter: defined in file [D:\springboot\Work_Java_eclipse\spring0123\target\classes\com\example\demo\CanonPrinter.class]
- hpPrinter: defined in file [D:\springboot\Work_Java_eclipse\spring0123\target\classes\com\example\demo\HpPrinter.class]
Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed
錯誤訊息: 因為沒有指定要載入的是哪個bean ,所以無法運行