先看例1
// 一個接口
public interface IOCService {
}
// 接口實現(xiàn)
@Service
public class IOCServiceImpl0 implements IOCService {
}
// 控制層
@Controller
public class TController {
@Autowired private IOCService iOCService0;
@Inject private IOCService iOCService01;
@Resource private IOCService iOCService011;
@RequestMapping("/t")
@ResponseBody
public void t() {
System.out.println(iOCService0);
System.out.println(iOCService01);
System.out.println(iOCService011);
}
}
打印結(jié)果
- @Inject 與 @Autowired : 在Spring的環(huán)境下,@Inject 和 @Autowired是相同的启上,@Inject是 jsr-330 定義的規(guī)范,@Autowired 為 Spring 注解店印,二者默認都是 byType 策略進行注入冈在。即 Spring會直接將 IOCService 類型的唯一 一個bean賦值給 iOCService0 這個成員變量
- @Resource :會先采用 byName 策略進行注入,如果byName 無法找到 會使用 byType 策略按摘,如上述例子中包券。我們沒有指定 name 纫谅,@Resource byName 無法找到bean,他會使用byType 策略進行注入溅固。
例2
這個時候付秕,我們?yōu)?IOCService 接口 增加一個實現(xiàn)類
@Service
public class IOCServiceImpl1 implements IOCService {
}
重啟項目,這個時候 注入拋出異常发魄,因為 當使用 byType 策略注入的時候 Spring 注入的接口所對應(yīng)的bean 必須是唯一的盹牧,當有兩個實現(xiàn)類的時候 Spring會找到 IOCService 的兩個實例。
nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type 'com.wansidong.communicate.test.IOCService' available:
expected single matching bean but found 2: IOCServiceImpl0,IOCServiceImpl1
這時候需要使用 byName 策略進行注入
@Controller
public class TController {
@Autowired
@Qualifier("IOCServiceImpl0")
private IOCService iOCService0;
@Inject
@Qualifier("IOCServiceImpl0")
private IOCService iOCService00;
@Resource(name="IOCServiceImpl0")
private IOCService iOCService000;
@Autowired
@Qualifier("IOCServiceImpl1")
private IOCService iOCService1;
@Inject
@Named("IOCServiceImpl1")
private IOCService iOCService11;
@Resource(name="IOCServiceImpl1")
private IOCService iOCService111;
@RequestMapping("/t")
@ResponseBody
public void t() {
System.out.println("--------------------注入 IOCServiceImpl0");
System.out.println(iOCService0);
System.out.println(iOCService00);
System.out.println(iOCService000);
System.out.println("--------------------注入 IOCServiceImpl1");
System.out.println(iOCService1);
System.out.println(iOCService11);
System.out.println(iOCService111);
}
}
打印結(jié)果如下
- @Qualifier 與 @Named :可以看到 這兩個注解配合 @Autowired 和 @Inject 都可以實現(xiàn) byName 方式注入
- @Resource : 通過設(shè)置 @Resource(name="xxx") 完成 byName 注入
疑問:
寫到這兒的時候励幼,我發(fā)現(xiàn)一個問題,如果哪位知道的朋友口柳,看到了可以私信苹粟,評論告訴我。
我記得之前 我看過 Spring 通過@Controller @Service 創(chuàng)建的bean name 默認是首字母小寫的類名跃闹,但是我這里拋出的 異常打印 bean 名稱 是大寫嵌削,而且我在指定 name 的時候 首字母小寫也會報錯,說明 Spring 為我創(chuàng)建的 bean 和 類名相同 望艺,為什么呢苛秕?
對于 Spring 深層次的理解還是不夠, 如果文章中哪里說的不對找默,還望各位看官指出艇劫。