Springboot筆記<4>@Autowired和@Resource的區別
@Autowired和@Resource的區別
@Resource
有兩個常用屬性name、type,所以分4種情況
- 指定name和type:通過name找到唯一的bean,找不到丟擲異常;如果type和欄位型別不一致,也會丟擲異常
- 指定name:通過name找到唯一的bean,找不到丟擲異常
- 指定type:通過tpye找到唯一的bean,如果不唯一,則丟擲異常:NoUniqueBeanDefinitionException
- 都不指定:通過欄位名作為key去查詢,找到則賦值;找不到則再通過欄位型別去查詢,如果不唯一,則丟擲異常:NoUniqueBeanDefinitionException
@Autowired
@Autowired由Spring提供,只按照byType注入
@Autowired只有一個屬性required,預設值為true,為true時,找不到就拋異常,為false時,找不到就賦值為null
@Autowired按型別查詢,如果該型別的bean不唯一,則丟擲異常;可通過組合註解解決@Autowired()@Qualifier("baseDao")
相同點
- Spring都支援
- 都可以作用在欄位和setter方法上
不同點
- Resource是JDK提供的,而Autowired是Spring提供的
- Resource不允許找不到bean的情況,而Autowired允許(
@Autowired(required = false)
- 指定name的方式不一樣,
@Resource(name = "baseDao")
,@Autowired()@Qualifier("baseDao")
- Resource預設通過name查詢,而Autowired預設通過type查詢
總結
@Autowired自動註解,一個類,倆個實現類,Autowired就不知道注入哪一個實現類,需要配合@Qualifier按照name注入,而Resource有name屬性,可以區分。
舉例說明
@Autowired
在service層,讓StudentServiceImpl1,StudentServiceImpl2實現StudentService藉口
在controller層,使用@Autowired注入則會丟擲異常,idea直接提示使用@Qualifier進行區分,解決方案有四種:
1:@Autowired+@Qualifier("studentServiceImpl1")則可以進行區分
2:去掉一個StudentService的實現類,則可以直接按照型別進行裝配
3:**@Autowired+@Primary****,自動裝配時當出現多個Bean候選者時,被註解為@Primary的Bean將作為首選者,否則將丟擲異常。(只對介面的多個實現生效)
4: @Resource(name = "studentServiceImpl1"),不指定name會丟擲異常。如果只有StudentServiceImpl1,刪掉StudentServiceImpl2,則可以直接使用@Resource,根據型別查詢唯一值
@Service
public class StudentServiceImpl1 implements StudentService {
@Override
public void getStudentAge() {
System.out.println("查到學生的年齡");
}
}
@Service
public class StudentServiceImpl2 implements StudentService {
@Override
public void getStudentAge() {
System.out.println("查到學生的年齡");
}
}
錯誤寫法:
@Slf4j
@RestController
public class StudentController {
@Autowired
@Qualifier("studentServiceImpl1")
StudentService studentService;
@RequestMapping("/student")
public String handle01(){
studentService.getStudentAge();
return "student";
}
}
正確的@Autowired+@Qualifier寫法:
@Slf4j
@RestController
public class StudentController {
@Autowired
@Qualifier("studentServiceImpl1")
StudentService studentService;
@RequestMapping("/student")
public String handle01(){
studentService.getStudentAge();
return "student";
}
}
正確的@Autowired+@Primary寫法:
@Service
@Primary
public class StudentServiceImpl1 implements StudentService {
@Override
public void getStudentAge() {
System.out.println("查到學生的年齡");
}
}
正確的@Resource寫法:
@Slf4j
@RestController
public class StudentController {
@Resource(name = "studentServiceImpl1")
StudentService studentService;
@RequestMapping("/student")
public String handle01(){
studentService.getStudentAge();
return "student";
}
}
未經作者同意請勿轉載
本文來自部落格園作者:aixueforever,原文連結:https://www.cnblogs.com/aslanvon/p/15715130.html