相信對現在Java碼農來說,@Autowired跟@Resource並不陌生,二者都可以自動註入,但是兩者的區別很多時候並沒有被註意到。 一、註解的出處 @Autowired是Spring提供的註解,需要導入包org.springframework.beans.factory.annotation. ...
相信對現在Java碼農來說,@Autowired跟@Resource並不陌生,二者都可以自動註入,但是兩者的區別很多時候並沒有被註意到。
一、註解的出處
@Autowired是Spring提供的註解,需要導入包org.springframework.beans.factory.annotation.Autowired
@Resource是由J2EE提供的註解,需要導入包javax.annotation.Resource
也就是說@Autowired是外部包導入的,而@Resource是J2EE自己的
二、自動註入規則
@Autowired預設按照byType自動註入
@Autowired採取的是按照類型進行自動註入的,Autowired源碼中只有一個屬性required(稍後介紹)。
說明@Autowired無法人為去干預註入規則的,然後當容器中同一類型的bean存在多個的話,@Autowired該如何去選擇呢,這時就需要@Qualifier註解來幫忙了。
@Qualifier跟@Autowired來自同一包下,存在一個屬性value,我們可以通過value屬性來確定@Autowired具體註入的是哪一個bean。
如果匹配不到對象時,將會拋出異常 BeanCreationException。
如果匹配到多個對象時,也會拋出異常。
public class UserService { @Autowired @Qualifier(value="userDao1") private UserDao userDao; private ManDao manDao; @Autowired public void setUserDao(@Qualifier("manDao") ManDao manDao) { this.manDao = manDao; } }
@Resource預設按照byName自動註入
@Resource註解在註入規則上存在兩個屬性:name、type
1、若沒有使用屬性,則通過反射機制,預設按照byName方式進行裝配,如果沒有匹配,則再類型進行裝配;
2、若只使用了name屬性,則使用byName的自動註入策略,從上下文中查找名稱id,如果匹配不到則拋出異常;
3、若只使用了type屬性,則使用byType自動註入策略,從上下文中找到類型匹配的唯一bean進行裝配,找不到或者找到多個都會拋出異常;
4、若兩個屬性都使用了,則需要找到唯一匹配的bean進行裝配,找不到則拋出異常。
public class UserService { @Resource private UserDao userDao; @Resource(name="studentDao") private StudentDao studentDao; @Resource(type="TeacherDao") private TeacherDao teacherDao; @Resource(name="manDao",type="ManDao") private ManDao manDao; }
三、註入時對象是否存在
@Autowired:預設按照類型進行裝配,預設情況下要求依賴的對象必須存在,如果需要允許null值,則需要設置required屬性為false,@Autowired(required=false)。
@Resource:預設按照名稱進行裝配,允許為null。
四、使用位置
兩者都可以寫在欄位和setter方法上,如果寫在欄位上,那麼就不需要在寫setter方法。
推薦使用@Resource註解在欄位上,這樣不僅不需要寫setter方法了,而且由於@Resource屬於J2EE,降低與spring的耦合。