寫在前面
我在 冰河技術 微信公眾號中發表的《【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均是由冰河原創並整理的超硬核教程,面試必備!!
好了,今天就聊到這兒吧!別忘了點個贊,給個在看和轉發,讓更多的人看到,一起學習,一起進步!!
寫在最後
如果你覺得冰河寫的還不錯,請微信搜尋並關注「 冰河技術 」微信公眾號,跟冰河學習高併發、分散式、微服務、大資料、網際網路和雲原生技術,「 冰河技術 」微信公眾號更新了大量技術專題,每一篇技術文章乾貨滿滿!不少讀者已經通過閱讀「 冰河技術 」微信公眾號文章,吊打面試官,成功跳槽到大廠;也有不少讀者實現了技術上的飛躍,成為公司的技術骨幹!如果你也想像他們一樣提升自己的能力,實現技術能力的飛躍,進大廠,升職加薪,那就關注「 冰河技術 」微信公眾號吧,每天更新超硬核技術乾貨,讓你對如何提升技術能力不再迷茫!