1. 程式人生 > 其它 >Autowired和Resource的區別和聯絡

Autowired和Resource的區別和聯絡

聯絡
@Autowired和@Resource註解都是作為bean物件注入的時候使用的
兩者都可以宣告在欄位和setter方法上
注意:如果宣告在欄位上,那麼就不需要再寫setter方法。但是本質上,該物件還是作為set方法的實參,通過執行set方法注入,只是省略了setter方法罷了

區別
@Autowired註解是Spring提供的,而@Resource註解是J2EE本身提供的
@Autowird註解預設通過byType方式注入,而@Resource註解預設通過byName方式注入
@Autowired註解注入的物件需要在IOC容器中存在,否則需要加上屬性required=false,表示忽略當前要注入的bean,如果有直接注入,沒有跳過,不會報錯
對於byName和byType方式不太熟悉的可以看一下這裡:Spring中的byName與byType

簡單來說,byName就是變數名去匹配bean的id屬性,而byType則是變數型別去匹配bean的class屬性

<bean id="userService" class="com.test.UserServiceImpl">
</bean>

@Autowired
private UserService userService;

此處byName就是拿變數名userService去匹配IOC容器的iduserService,匹配成功;而byType就是拿變數型別UserService去匹配IOC容器的idcom.test.UserService.UserServiceImpl,因為UserServiceImpl是UserService實現,所以也匹配成功

接下來再分別講講@Autowired註解和@Resource註解的使用

@Autowird註解的使用
步驟:@Autowird預設的注入方式為byType,也就是根據型別匹配,當有多個實現時,則通過byName注入,也可以通過配合@Qualifier註解來顯式指定name值,指明要使用哪個具體的實現類

舉例:

首先有一個介面UserService和兩個實現類UserServiceImpl1和UserServiceImpl2,並且這兩個實現類已經加入到Spring的IOC容器中了

@Service
public class UserServiceImpl1 implements UserService

@Service
public class UserServiceImpl2 implements UserService

通過@Autowired注入使用

@Autowired
private UserService userService;

根據上面的步驟,可以很容易判斷出,直接這麼使用是會報錯的
原因:首先通過byType注入,判斷UserService型別有兩個實現,無法確定具體是哪一個,於是通過byName方式,這裡的變數名userService也無法匹配IOC容器中id(此處指的userServiceImpl1和userServiceImpl2),於是報錯。

注意:通過註解注入到IOC容器的id值預設是其類名首字母小寫

解決方案

方式一:

// 方式一:改變變數名
@Autowired
private UserService userServiceImpl1;

方式二:

// 方式二:配合@Qualifier註解來顯式指定name值
@Autowired
@Qualifier(value = "userServiceImpl1")
private UserService userService;

@Resource註解的使用
步驟:@Resource預設通過byName注入,如果沒有匹配則通過byType注入

舉例:

@Service
public class UserServiceImpl1 implements UserService

@Service
public class UserServiceImpl2 implements UserService

@Resource
private UserService userService;

首先通過byName匹配,變數名userService無法匹配IOC容器中任何一個id(這裡指的userServiceImpl1和userServiceImpl2),於是通過byType匹配,發現型別UserService的實現類有兩個,仍然無法確定,於是報錯。

同時@Resource還有兩個重要的屬性:name和type,用來顯式指定byName和byType方式注入

使用:對應4種情況

// 1. 預設方式:byName
@Resource
private UserService userDao;

// 2. 指定byName
@Resource(name="userService")
private UserService userService;

// 3. 指定byType
@Resource(type=UserService.class)
private UserService userService;

// 4. 指定byName和byType
@Resource(name="userService",type=UserService.class)
private UserService userService;

既沒指定name屬性,也沒指定type屬性:預設通過byName方式注入,如果byName匹配失敗,則使用byType方式注入(也就是上面的那個例子)
指定name屬性:通過byName方式注入,把變數名和IOC容器中的id去匹配,匹配失敗則報錯
指定type屬性:通過byType方式注入,在IOC容器中匹配對應的型別,如果匹配不到或者匹配到多個則報錯
同時指定name屬性和type屬性:在IOC容器中匹配,名字和型別同時匹配則成功,否則失敗