天天看點

spring 注解@Resource 和 @Autowired的差別

@Resource的作用相當于@Autowired,隻不過@Autowired按byType自動注入,而@Resource預設按 byName自動注入罷了。@Resource有兩個屬性是比較重要的,分是name和type,Spring将@Resource注解的name屬性解析為bean的名字,而type屬性則解析為bean的類型。是以如果使用name屬性,則使用byName的自動注入政策,而使用type屬性時則使用byType自動注入政策。如果既不指定name也不指定type屬性,這時将通過反射機制使用byName自動注入政策。

  @Resource裝配順序

  1. 如果同時指定了name和type,則從Spring上下文中找到唯一比對的bean進行裝配,找不到則抛出異常

  2. 如果指定了name,則從上下文中查找名稱(id)比對的bean進行裝配,找不到則抛出異常

  3. 如果指定了type,則從上下文中找到類型比對的唯一bean進行裝配,找不到或者找到多個,都會抛出異常

  4. 如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有比對,則回退為一個原始類型進行比對,如果比對則自動裝配; 

@Autowired注解是按類型裝配依賴對象,預設情況下它要求依賴對象必須存在,如果允許null值,可以設定它required屬性為false。如果我們想使用按名稱裝配,可以結合@Qualifier注解一起使用。如下: 

    @Autowired  @Qualifier("personDaoBean") 

    private PersonDao  personDao; 

@Resource注解和@Autowired一樣,也可以标注在字段或屬性的setter方法上,但它預設按名稱裝配。名稱可以通過@Resource的name屬性指定,如果沒有指定name屬性,當注解标注在字段上,即預設取字段的名稱作為bean名稱尋找依賴對象,當注解标注在屬性的setter方法上,即預設取屬性名作為bean名稱尋找依賴對象。 

    @Resource(name=“personDaoBean”) 

    private PersonDao  personDao;//用于字段上 

注意:如果沒有指定name屬性,并且按照預設的名稱仍然找不到依賴對象時, @Resource注解會回退到按類型裝配。但一旦指定了name屬性,就隻能按名稱裝配了。

下面來詳細了解一下@Autowired以及與其相似的@Resource 1, @Autowired是Spring的方法。      @Resource是Java(JSR-250)的方法。 2, @Autowired:類型一緻注入         @Autowired(required=false)        private UserInfoDao userInfoDao;           UserInfoDao類型的class有的情況下,就自動 注入 ( 設定 )             UserInfoDao類型的class沒有的情況下,不自動 注入 ( 設定 ),也不産生error.          @Autowired(required=true)        private UserInfoDao userInfoDao;           UserInfoDao類型的class有的情況下,就自動 注入 ( 設定 )             UserInfoDao類型的class沒有的情況下,不自動 注入 ( 設定 ),産生error.           required選項預設是TURE    @Resource :名稱 一緻注入          @Resource(name="userInfoDao")         private UserInfoDao userInfoDao;        用名稱是 userInfoDao的類來注入。          @ Resource         private UserInfoDao userInfoDao;        用和變量名 userInfoDao 一緻的類來注入。 這裡會有一個問題,在使用類型對應的 @Autowired的時候,可能會有多個候選項的情況,怎麼辦呢? 答案是用@Qualifier來指定 候選項的ID。        @Autowired        @Qualifier("main")        private UserInfoDao userInfoDao; 3,修飾的範圍不同。     @Autowired:屬性,方法,構造函數 加在任意名,多個參數的方法上。

public class MovieRecommender {

  private MovieCatalog movieCatalog;

  private CustomerPreferenceDao customerPreferenceDao;

  @Autowired
  public void prepare(MovieCatalog movieCatalog,
                      CustomerPreferenceDao customerPreferenceDao) {
      this.movieCatalog = movieCatalog;
      this.customerPreferenceDao = customerPreferenceDao;
  }

  // ...
}      

加在屬性和構造函數上。

public class MovieRecommender {

  @Autowired
  private MovieCatalog movieCatalog;

  private CustomerPreferenceDao customerPreferenceDao;

  @Autowired
  public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) {
      this.customerPreferenceDao = customerPreferenceDao;
  }

  // ...
}      

    @Resource : 屬性,隻有一個參數的Bean的setter方法

public class SimpleMovieLister {

  private MovieFinder movieFinder;

  @Resource(name="myMovieFinder")
  public void setMovieFinder(MovieFinder movieFinder) {
      this.movieFinder = movieFinder;
  }       
public class MovieRecommender {

  @Resource
  private CustomerPreferenceDao customerPreferenceDao;

  @Resource
  private ApplicationContext context;

  public MovieRecommender() {
  }

  // ... 
      

如果想用名稱來實作Spring注釋的注入的話,@Resource比@Autowired更好。 還有Collection和Map不能用 @Autowired來實作注入,可以用 @Resource。

// @Autowired @Qualifier("prefsList") は NG
  @Resource(name = "prefsList")
  private List<String> prefs;