@Resource
和@Autowired
註解均可以在Spring Framework應用中進行聲明式的依賴注入。並且面試中常常涉及到這兩個註解的知識點。今天咱們來總結一下它們。html
全稱javax.annotation.Resource
,它屬於JSR-250規範的一個註解,包含Jakarta EE(J2EE)中。Spring提供了對該註解的支持。咱們來詳細瞭解一下該註解的規則。java
該註解使用在成員屬性和setter方法上。默認狀況下@Resource
按照名稱注入,若是沒有顯式聲明名稱則按照變量名稱或者方法中對應的參數名稱進行注入。面試
若是咱們但願在目標Bean中體現多態咱們能夠這樣寫:spring
/** * 多態的體現. * * @author felord.cn * @since 9 :26 */
@Component
public class ResourceTest {
@Resource
private ApplicationRunner applicationRunner;
@Resource
private ApplicationRunner runner;
// ...
}
複製代碼
Qualifier 約束參見 Spring 註解 @Qualifier 詳細解析數組
@Autowired
一般適用於構造函數,成員變量以及方法上。它的機制是這樣的:app
這個註解咱們是須要好好聊聊的,平常使用頻率至關高。函數
經過在目標Bean的構造函數上標註就能夠注入對應的Bean。ui
package cn.felord;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationRunner;
import org.springframework.stereotype.Component;
/** * @author felord.cn * @since 9:26 **/
@Component
public class AutowiredTest {
private final ApplicationRunner applicationRunner;
@Autowired
public AutowiredTest(ApplicationRunner applicationRunner) {
this.applicationRunner = applicationRunner;
}
}
複製代碼
從Spring Framework 4.3開始,
@Autowired
若是目標Bean只定義一個構造函數,則再也不須要在該構造函數上添加@Autowired
註解。若是目標Bean有幾個構造函數可用,而且沒有主/默認構造函數,則必須至少有一個構造函數被@Autowired
標記,以指示Spring IoC容器使用哪一個構造函數。this
和@Resource
同樣,@Autowired
也能夠標註到目標Bean的成員變量上。spa
/** * @author felord.cn * @since 9:26 **/
@Component
public class AutowiredTest {
@Autowired
private ApplicationRunner applicationRunner;
// ...
}
複製代碼
通常setter方法上使用的比較多。並且一個 @Autowired
支持注入多個參數。
/** * The type Autowired test. * * @author felord.cn * @since 9 :26 */
@Component
public class AutowiredTest {
private ApplicationRunner applicationRunner;
private EmployeeMapper employeeMapper;
private DepartmentMapper departmentMapper;
/** * Sets application runner. * * @param applicationRunner the application runner */
@Autowired
public void setApplicationRunner(ApplicationRunner applicationRunner) {
this.applicationRunner = applicationRunner;
}
/** * 支持多參數 * * @param employeeMapper the employee mapper * @param departmentMapper the department mapper */
@Autowired
public void prepare(EmployeeMapper employeeMapper, DepartmentMapper departmentMapper) {
this.employeeMapper = employeeMapper;
this.departmentMapper = departmentMapper;
}
}
複製代碼
你覺得這就完了?下面這種方式估計大多數人並無在乎過。
/** * The type Autowired test. * * @author felord.cn * @since 9 :26 */
@Component
public class AutowiredTest {
// 注入 數組
@Autowired
private MovieCatalog[] movieCatalogs;
private Map<String, Movie> movies;
private Set<CustomerPreferenceDao> customerPreferenceDaos;
// 注入 set
@Autowired
public MovieRecommender(Set<CustomerPreferenceDao> customerPreferenceDaos) {
this.customerPreferenceDaos = customerPreferenceDaos;
}
// 注入 map
@Autowired
public void setMovieCatalogs(Map<String, Movie> movies) {
this.movies = movies;
}
// ...
}
複製代碼
能夠把Bean注入目標Bean的數組、集合容器中去。默認狀況下,當給定注入點沒有匹配的候選Bean可用時,自動裝配將失敗。至少應有一個匹配元素。
若是您但願元素按照特定順序排序,則元素Bean能夠實現
org.springframework.core.Ordered
接口或者對應註解@Order
或標準@Priority
。基於某些機制不建議使用註解方式來排序,不然沒法達到預期指望,推薦使用接口Ordered
。
@Resource
沒有提供可選擇裝配的特性,一旦沒法裝配則會拋出異常;而@Autowired
提供了required
屬性(默認值爲true
)以免這種狀況,設置@Autowired
爲false
。
/** * The type Autowired test. * * @author felord.cn * @since 9 :26 */
@Component
public class AutowiredTest {
// 一旦找不到 movieFinder 不會異常 而初始化爲 null
@Autowired(required = false)
private MovieFinder movieFinder;
// ...
}
複製代碼
這裏也有騷操做,你能夠忽略required
屬性。經過 Java 8的 java.util.Optional
來代表候選Bean可選。
/** * The type Autowired test. * * @author felord.cn * @since 9 :26 */
@Component
public class AutowiredTest {
public class SimpleMovieLister {
// 使用 Optional 代表候選Bean可選
@Autowired
public void setMovieFinder(Optional<MovieFinder> movieFinder) {
// ...
}
}
複製代碼
從Spring 5.0開始,您還可使用@Nullable
註解,這個註解能夠你本身實現檢測邏輯或者直接使用 JSR-305提供的javax.annotation.Nullable
。
/** * The type Autowired test. * * @author felord.cn * @since 9 :26 */
@Component
public class AutowiredTest {
public class SimpleMovieLister {
// 使用 @Nullable 註解代表候選Bean可選
@Autowired
public void setMovieFinder(@Nullable MovieFinder movieFinder) {
// ...
}
}
複製代碼
從Spring 3.0開始,Spring提供對JSR-330標準註解(依賴注入)的支持。 你須要引入依賴:
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
複製代碼
而後你就可使用相關的註解來進行依賴注入了,其中主要註解爲@javax.inject.Inject
。大部分狀況下該註解均可以代替@Autowired
使用,但@Inject
沒有required
屬性,不過它也能夠與java.util.Optional
或使用@Nullable
來達到一樣的效果。
大部分狀況下沒有人喜歡額外引入Jakarta EE依賴來使用一個已經擁有的功能,Spring堵死了Jakarta EE依賴注入的生態。
@Resource
和@Autowired
的優先級順序不一樣(參見上圖),另外@Resource
屬於 Jakarta EE規範而@Autowired
屬於Spring
範疇,@Resource
沒法使用在構造參數中,@Autowired
支持required
屬性。從面向對象來講,@Resource
更加適用於多態性的細粒度注入,而@Autowired
更多專一於多態的單例注入。@Inject
則不必過多討論,只做爲一個添頭。好了今天就到這裏,多多關注:碼農小胖哥,更多幹貨知識分享。
關注公衆號:Felordcn獲取更多資訊