1.使用場景
@Resource和@Autowired都是做bean注入時使用
@Resource是jdk的注解,不是spring的注解;由包javax.annotation.Resource提供,需要導入,但是Spring支持該注解注入
2.相同點,不同點
共同點:兩者都可以寫在setter方法,和字段上,不需要再寫setter方法
不同點:
2.1 @Autowired是spring提供的注解,只按照byType注入
public class TestServiceImpl {
// 下面兩種@Autowired只要使用一種即可
@Autowired
private UserDao userDao; // 用於字段上
@Autowired
public void setUserDao(UserDao userDao) { // 用於屬性的方法上
this.userDao = userDao;
}
}
Autowired是按照類型byType裝配依賴對象,默認情況下它要求依賴對象必須存在,如果允許null值,可以設置required屬性值為false。如果想按照名稱(byName)來裝配,可以結合Qualifier注解一起使用
(通過類型匹配多個candidate,在沒有Qualifier的情況下,會使用對象名作為最后的fallback匹配)
public class TestServiceImpl {
@Autowired
@Qualifier("userDao")
private UserDao userDao;
}
2.2 @Resource
Resource默認是按照ByName自動注入的,@Resource有兩個屬性:name和type
spring將@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型
如果使用name屬性,使用byName自動注入策略,而使用 type屬性時則使用byType自動注入策略
如果既不指定name也不指定type屬性,這是將通過反射機制使用byName自動注入策略
public class TestServiceImpl {
// 下面兩種@Resource只要使用一種即可
@Resource(name="userDao")
private UserDao userDao; // 用於字段上
@Resource(name="userDao")
public void setUserDao(UserDao userDao) { // 用於屬性的setter方法上
this.userDao = userDao;
}
}
@Resource裝配順序:
①如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常。
②如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常。
③如果指定了type,則從上下文中找到類似匹配的唯一bean進行裝配,找不到或是找到多個,都會拋出異常。
④如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始類型進行匹配,如果匹配則自動裝配。
@Resource的作用相當於@Autowired,只不過@Autowired按照byType自動注入。
在啟動spring的時候,首先要啟動容器;
啟動spring容器時,會默認尋找容器掃描范圍內的可加載bean,然后查找哪些bean上的屬性和方法上有@Resource注解;
找到@Resource注解后,判斷@Resource注解括號中的name屬性是否為空,如果為空:看spring容器中的bean的id與@Resource要注解的那個變量屬性名是否相同,如相同,匹配成功;如果不相同,看spring容器中bean的id對應的類型是否與@Resource要注解的那個變量屬性對應的類型是否相等,若相等,匹配成功,若不相等,匹配失敗。
如果@Resource注解括號中的name屬性不為空,看name的屬性值和容器中的bean的id名是否相等,如相等,則匹配成功;如不相等,則匹配失敗。