Spring中@Autowired、@Resource和@Inject注解的使用和區別


在使用Spring進行項目開發的時候,會大量使用到自動裝配,那自動裝配是什么呢?簡單來說:Spring 利用依賴注入(DI)功能,完成SpringIOC容器中各個組件之間的依賴關系賦值管理。

下面介紹和總結可以在在Spring使用的三種自動注入的注解。首先回顧一下最初使用xml進行是如何進行注入的。

零、回顧:XML方式注入

使用 property 或者 constructor-arg 屬性。

<!-- 配置需要被Spring管理的Bean(創建,創建后放在了Spring IOC容器里面)-->
<bean id="superMan" class="org.annotation.autowried.SuperMan">
 <property name="car" ref="car"></property>
 <!--<constructor-arg ref="car"/>--> 
</bean>
<bean id="car" class="org.annotation.autowried.Car"/>
public class SuperMan {
 private Car car;
 /* private SuperMan(Car car){
 this.car = car;
 }*/
 public void setCar(Car car) {
 this.car = car;
 }
}
public class Car {
 private String brand = "喇嘛殺敵";
}

這樣就能夠將需要的組件注入到Spring中,並且進行組件中的依賴關系管理。回顧結束,通過這種方式來,配置比較繁瑣,下面正式進入使用注解注入的主題。

@Autowired介紹

在Spring 2.5 引入了 @Autowired 注解!

@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
 boolean required() default true;
}

從Autowired注解源碼上看,可以使用在下面這些地方:

@Target(ElementType.CONSTRUCTOR) #構造函數
@Target(ElementType.METHOD) #方法
@Target(ElementType.PARAMETER) #方法參數
@Target(ElementType.FIELD) #字段、枚舉的常量
@Target(ElementType.ANNOTATION_TYPE) #注解

還有一個value屬性,默認是true。

簡單總結:

1、@Autowired是Spring自帶的注解,通過AutowiredAnnotationBeanPostProcessor 類實現的依賴注入

2、@Autowired可以作用在CONSTRUCTOR、METHOD、PARAMETER、FIELD、ANNOTATION_TYPE

3、@Autowired默認是根據類型(byType )進行自動裝配的

4、如果有多個類型一樣的Bean候選者,需要指定按照名稱(byName )進行裝配,則需要配合@Qualifier。

指定名稱后,如果Spring IOC容器中沒有對應的組件bean拋出NoSuchBeanDefinitionException。也可以將@Autowired中required配置為false,如果配置為false之后,當沒有找到相應bean的時候,系統不會拋異常

簡單使用代碼:

在字段屬性上。

@Autowired
private HelloDao helloDao;

或者

private HelloDao helloDao;
public HelloDao getHelloDao() {
 return helloDao;
}
@Autowired
public void setHelloDao(HelloDao helloDao) {
 this.helloDao = helloDao;
}

或者

private HelloDao helloDao;
//@Autowired
public HelloServiceImpl(@Autowired HelloDao helloDao) {
 this.helloDao = helloDao;
}
// 構造器注入也可不寫@Autowired,也可以注入成功。

將@Autowired寫在被注入的成員變量上,setter或者構造器上,就不用再xml文件中配置了。

如果有多個類型一樣的Bean候選者,則默認根據設定的屬性名稱進行獲取。如 HelloDao 在Spring中有 helloWorldDao 和 helloDao 兩個Bean候選者。

@Autowired
private HelloDao helloDao;

首先根據類型獲取,發現多個HelloDao,然后根據helloDao進行獲取,如果要獲取限定的其中一個候選者,結合@Qualifier進行注入。

@Autowired
@Qualifier("helloWorldDao")
private HelloDao helloDao;

注入名稱為helloWorldDao 的Bean組件。@Qualifier("XXX") 中的 XX是 Bean 的名稱,所以 @Autowired 和 @Qualifier 結合使用時,自動注入的策略就從 byType 轉變成 byName 了。

多個類型一樣的Bean候選者,也可以@Primary進行使用,設置首選的組件,也就是默認優先使用哪一個。

注意:使用@Qualifier 時候,如何設置的指定名稱的Bean不存在,則會拋出異常,如果防止拋出異常,可以使用:

@Qualifier("xxxxyyyy")
@Autowired(required = false)
private HelloDao helloDao;

在SpringBoot中也可以使用@Bean+@Autowired進行組件注入,將@Autowired加到參數上,其實也可以省略。

@Bean
public Person getPerson(@Autowired Car car){
 return new Person();
}
// @Autowired 其實也可以省略

@Resource介紹

@Target({TYPE, FIELD, METHOD})
@Retention(RUNTIME)
public @interface Resource {
 String name() default "";
 // 其他省略
}

從Resource注解源碼上看,可以使用在下面這些地方:

@Target(ElementType.TYPE) #接口、類、枚舉、注解
@Target(ElementType.FIELD) #字段、枚舉的常量
@Target(ElementType.METHOD) #方法

name 指定注入指定名稱的組件。

簡單總結:

1、@Resource是JSR250規范的實現,在javax.annotation包下

2、@Resource可以作用TYPE、FIELD、METHOD上

3、@Resource是默認根據屬性名稱進行自動裝配的,如果有多個類型一樣的Bean候選者,則可以通過name進行指定進行注入

簡單使用代碼:

@Component
public class SuperMan {
 @Resource
 private Car car;
}

按照屬性名稱 car 注入容器中的組件。如果容器中BMW還有BYD兩種類型組件。指定加入BMW。如下代碼:

@Component
public class SuperMan {
 @Resource(name = "BMW")
 private Car car;
}

name 的作用類似 @Qualifier!

@Inject介紹

@Target({ METHOD, CONSTRUCTOR, FIELD })
@Retention(RUNTIME)
@Documented
public @interface Inject {}

從Inject注解源碼上看,可以使用在下面這些地方:

@Target(ElementType.CONSTRUCTOR) #構造函數
@Target(ElementType.METHOD) #方法
@Target(ElementType.FIELD) #字段、枚舉的常量

簡單總結:

1、@Inject是JSR330 (Dependency Injection for Java)中的規范,需要導入javax.inject.Inject jar包 ,才能實現注入

2、@Inject可以作用CONSTRUCTOR、METHOD、FIELD上

3、@Inject是根據類型進行自動裝配的,如果需要按名稱進行裝配,則需要配合@Named;

簡單使用代碼:

@Inject
private Car car;

指定加入BMW組件。

@Inject
@Named("BMW")
private Car car;

@Named 的作用類似 @Qualifier!

總結

1、@Autowired是Spring自帶的,@Resource是JSR250規范實現的,@Inject是JSR330規范實現的

2、@Autowired、@Inject用法基本一樣,不同的是@Inject沒有一個request屬性

3、@Autowired、@Inject是默認按照類型匹配的,@Resource是按照名稱匹配的

4、@Autowired如果需要按照名稱匹配需要和@Qualifier一起使用,@Inject和@Name一起使用,@Resource則通過name進行指定

 

轉自:https://www.toutiao.com/i6725012978053153291/?tt_from=weixin&utm_campaign=client_share&wxshare_count=1&timestamp=1568424622&app=news_article&utm_source=weixin&utm_medium=toutiao_android&req_id=2019091409302201002607602300CDF3ED&group_id=6725012978053153291


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM