【Spring註解驅動開發】你還不會使用@Resource和@Inject註解?那你就out了!!

冰河團隊發表於2020-08-13

寫在前面

我在 冰河技術 微信公眾號中發表的《【Spring註解驅動開發】使用@Autowired@Qualifier@Primary三大註解自動裝配元件,你會了嗎?》一文中,介紹瞭如何使用@Autowired、@Qualifier和@Primary註解自動裝配Spring元件。那除了這三個註解以外,還有沒有其他的註解可以自動裝配元件呢?那必須有啊!今天,我們就一起說說@Resource註解和@Inject註解。

關注 冰河技術 微信公眾號,回覆 “Spring註解”關鍵字領取原始碼工程。

@Resource註解

@Resource(這個註解屬於J2EE的,JSR250),預設安照名稱進行裝配,名稱可以通過name屬性進行指定, 如果沒有指定name屬性,當註解寫在欄位上時,預設取欄位名進行按照名稱查詢,如果註解寫在setter方法上預設取屬性名進行裝配。 當找不到與名稱匹配的bean時才按照型別進行裝配。但是需要注意的是,如果name屬性一旦指定,就只會按照名稱進行裝配。

@Resource註解的原始碼如下所示。

package javax.annotation;
import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.*;
@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
    String name() default "";
    String lookup() default "";
    Class<?> type() default java.lang.Object.class;
    enum AuthenticationType {
            CONTAINER,
            APPLICATION
    }
    AuthenticationType authenticationType() default AuthenticationType.CONTAINER;
    boolean shareable() default true;
    String mappedName() default "";
    String description() default "";
}

@Inject註解

@Inject註解(JSR330)預設是根據引數名去尋找bean注入,支援spring的@Primary註解優先注入,@Inject註解可以增加@Named註解指定注入的bean。

@Inject註解的原始碼如下所示。

package javax.inject;
import java.lang.annotation.Target;
import java.lang.annotation.Retention;
import java.lang.annotation.Documented;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Inject {}

注意:要想使用@Inject註解,需要在專案的pom.xml檔案中新增如下依賴。

<dependency>
    <groupId>javax.inject</groupId>
    <artifactId>javax.inject</artifactId>
    <version>1</version>
</dependency>

專案案例

測試@Resource註解

首先,我們將專案中的PersonService類標註在personDao欄位上的@Autowired註解和@Qualifier註解註釋掉,然後新增@Resource註解,如下所示。

//@Qualifier("personDao")
//@Autowired(required = false)
@Resource
private PersonDao personDao;

接下來,我們執行AutowiredTest類的testAutowired01()方法,輸出的結果資訊如下所示。

PersonService{personDao=PersonDao{remark='1'}}

可以看到,使用@Resource註解也能夠自動裝配元件,只不過此時自動裝配的是remark為1的personDao。而不是我們在AutowiredConfig類中配置的優先裝配的remark為2的personDao。AutowiredConfig類中配置的remark為2的personDao如下所示。

@Primary
@Bean("personDao2")
public PersonDao personDao(){
    PersonDao personDao = new PersonDao();
    personDao.setRemark("2");
    return personDao;
}

我們在使用@Resource註解時,可以通過@Resource註解的name屬性顯示指定要裝配的元件的名稱。例如,我們要想裝配remark為2的personDao,只需要為@Resource註解新增 name="personDao2"屬性即可。如下所示。

//@Qualifier("personDao")
//@Autowired(required = false)
@Resource(name = "personDao2")
private PersonDao personDao;

接下來,我們再次執行AutowiredTest類的testAutowired01()方法,輸出的結果資訊如下所示。

PersonService{personDao=PersonDao{remark='2'}}

可以看到,此時輸出了remark為2的personDao,說明@Resource註解可以通過name屬性顯示指定要裝配的bean。

測試@Inject註解

在PersonService類中,將@Resource註解註釋掉,新增@Inject註解,如下所示。

//@Qualifier("personDao")
//@Autowired(required = false)
//@Resource(name = "personDao2")
@Inject
private PersonDao personDao;

修改完畢後,我們執行AutowiredTest類的testAutowired01()方法,輸出的結果資訊如下所示。

PersonService{personDao=PersonDao{remark='2'}}

可以看到,使用@Inject註解預設輸出的是remark為2的personDao。這是因為@Inject註解和@Autowired註解一樣,預設優先裝配使用了@Primary註解標註的元件。

@Resource和@Inject註解與@Autowired註解的區別

不同點

  • @Autowired是spring專有註解,@Resource是java中JSR250中的規範,@Inject是java中JSR330中的規範
  • @Autowired支援引數required=false,@Resource,@Inject都不支援
  • @Autowired,和@Inject支援@Primary註解優先注入,@Resource不支援
  • @Autowired通過@Qualifier指定注入特定bean,@Resource可以通過引數name指定注入bean,@Inject需要@Named註解指定注入bean

相同點

三種註解都可以實現bean的注入。

重磅福利

關注「 冰河技術 」微信公眾號,後臺回覆 “設計模式” 關鍵字領取《深入淺出Java 23種設計模式》PDF文件。回覆“Java8”關鍵字領取《Java8新特性教程》PDF文件。回覆“限流”關鍵字獲取《億級流量下的分散式限流解決方案》PDF文件,三本PDF均是由冰河原創並整理的超硬核教程,面試必備!!

好了,今天就聊到這兒吧!別忘了點個贊,給個在看和轉發,讓更多的人看到,一起學習,一起進步!!

寫在最後

如果你覺得冰河寫的還不錯,請微信搜尋並關注「 冰河技術 」微信公眾號,跟冰河學習高併發、分散式、微服務、大資料、網際網路和雲原生技術,「 冰河技術 」微信公眾號更新了大量技術專題,每一篇技術文章乾貨滿滿!不少讀者已經通過閱讀「 冰河技術 」微信公眾號文章,吊打面試官,成功跳槽到大廠;也有不少讀者實現了技術上的飛躍,成為公司的技術骨幹!如果你也想像他們一樣提升自己的能力,實現技術能力的飛躍,進大廠,升職加薪,那就關注「 冰河技術 」微信公眾號吧,每天更新超硬核技術乾貨,讓你對如何提升技術能力不再迷茫!

相關文章