欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

為什么Spring和IDEA都不推薦使用 @Autowired 注解

 更新時間:2022年04月02日 15:04:13   作者:時間靜止不是簡史  
本文主要介紹了為什么Spring和IDEA都不推薦使用 @Autowired 注解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

前言

請看下面幾個問題

  • Spring為什么不推薦使用@Autowired 注解?
  • 為什么推薦使用@Resource 代替 @Autowired 注解?
  • 如何快速使用構造注入代替 @Autowired ?
  • @Autowired, @Qualifier, @Resource, 三者有何區(qū)別?

下面, 我們帶著以上問題去梳理和學習, 體會知識之間的關聯(lián)性

Spring為什么不推薦使用@Autowired 注解

背景

做開發(fā)的同學可能都會發(fā)現(xiàn), idea 在我們經(jīng)常使用的@Autowired 注解上添加了警告
警告內(nèi)容是: Field injection is not recommended, 譯為: 不推薦使用屬性注入

在這里插入圖片描述

我們點擊右側三個小點查看描述, 可以看到信息如下圖

在這里插入圖片描述

原因詳情描述: Inspection info: Spring Team recommends: "Always use constructor based dependency injection in your beans. Always use assertions for mandatory dependencies".
譯為: Spring 團隊建議: 始終在您的 bean 中使用基于構造函數(shù)的依賴注入。始終對強制依賴項使用斷言

在這里插入圖片描述

原因

為什么 Spring 建議我們在Bean中使用構造注入呢?
想要回答這個問題, 我們需要了解 Spring的依賴注入(DI)方式
Spring常用的注入方式有: 簡單類型注入, 集合類型注入, 域?qū)傩宰詣幼⑷? 自動注入的類別, 空值注入, 構造注入
可以簡化為: 屬性注入, 構造方法注入, set 方法注入

下面, 來用代碼展示下三種方式注入

屬性注入
可以看到, 我們開發(fā)最常用的就是屬性注入

@RestController
public class AppointmentNumberConfigurationController {

    @Autowired
    private AppointmentNumberConfigurationService numberConfigurationService;
}

set 方法注入
set 方法注入也會用到@Autowired注解,但使用方式與屬性注入有所不同,
屬性注入是用在成員變量上,而set 方法的時候,是用在成員變量的Setter函數(shù)上。

@RestController
public class AppointmentNumberConfigurationController {


    private AppointmentNumberConfigurationService numberConfigurationService;

    @Autowired
    public void setNumberConfigurationService(AppointmentNumberConfigurationService numberConfigurationService) {
        this.numberConfigurationService = numberConfigurationService;
}

構造方法注入
Constructor Injection是構造器注入,是我們最為推薦的一種使用方式。
但是, 每次注入都按照這樣的流程去構造注入的話, 會顯得比較麻煩.
至于如何去簡化這一步驟, 我們可以繼續(xù)往下看.

@RestController
public class AppointmentNumberConfigurationController {

    final AppointmentNumberConfigurationService numberConfigurationService;
    
    public AppointmentNumberConfigurationController(AppointmentNumberConfigurationService numberConfigurationService) {
        this.numberConfigurationService = numberConfigurationService;
    }
    }

三種方式對比如下

在這里插入圖片描述

使用屬性注入可能會出現(xiàn)的問題

基于屬性注入的方式, 違背單一職責原則
因為現(xiàn)在的業(yè)務一般都會使用很多依賴, 但擁有太多的依賴通常意味著承擔更多的責任,而這顯然違背了單一職責原則.
并且類和依賴容器強耦合,不能在容器外使用。
基于屬性注入的方式, 容易導致Spring 初始化失敗
因為現(xiàn)在在Spring特別是Spring Boot使用中, 經(jīng)常會因為初始化的時候, 由于屬性在被注入前就引用而導致npe(空指針錯誤),
進而導致容器初始化失敗(類似下面代碼塊). Java 在初始化一個類時,
是按照 靜態(tài)變量或靜態(tài)語句塊 –> 實例變量或初始化語句塊 –> 構造方法 -> @Autowired 的順序。
所以在執(zhí)行這個類的構造方法時,person 對象尚未被注入,它的值還是 null。
通過@Autowired 注入, 又因為是 ByType 注入, 因此有可能會出現(xiàn)兩個相同的類型bean
如下代碼快, 就會產(chǎn)生兩個相同的Bean, 進而導致Spring 裝配失敗
//2. 基于屬性注入的方式, 容易導致Spring 初始化失敗
@Autowired
private Person person;

private String company;

public UserServiceImpl(){
    this.company = person.getCompany();
}


//3. 通過@Autowired 注入, 又因為是 ByType 注入, 因此有可能會出現(xiàn)兩個相同的類型bean
public interface IUser {
    void say();
}

@Service
public class User1 implements IUser{
    @Override
    public void say() {
    }
}

@Service
public class User2 implements IUser{
    @Override
    public void say() {
    }
}

@Service
public class UserService {

    @Autowired
    private IUser user;
} 

解決

如果一定要使用屬性注入, 可以使用 @Resource 代替 @Autowired 注解
@Resource的作用相當于@Autowired,只不過@Autowired按照byType自動注入。
如果我們想使用按照名稱byName來裝配,可以結合@Qualifier注解一起使用。

如果可能的話, 盡量使用構造注入
Lombok提供了一個注解@RequiredArgsConstructor, 可以方便我們快速進行構造注入, 例如:

@RestController
@RequiredArgsConstructor
public class AppointmentNumberConfigurationController {
    
    final AppointmentNumberConfigurationService numberConfigurationService;
    }

同時需要注意:

使用@RequiredArgsConstructor注解需要導入Lombok 包 或者安裝lombok 插件

  <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.16</version>
  </dependency>

必須聲明的變量為final

根據(jù)構造器注入的,相當于當容器調(diào)用帶有一組參數(shù)的類構造函數(shù)時,基于構造函數(shù)的 DI 就完成了,
其中每個參數(shù)代表一個對其他類的依賴?;跇嬙旆椒閷傩再x值,容器通過調(diào)用類的構造方法將其進行依賴注入

思考

為什么推薦使用@Resource,不推薦使用@Autowired

通過對問題1 的梳理, 我們可以知道.
因為@Autowired 注解在Bean 注入的時候是基于ByType, 因此會由于注入兩個相同類型的Bean導致裝配失敗

@Resource的作用相當于@Autowired,只不過@Autowired按照byType自動注入。
如果我們想使用按照名稱byName來裝配,可以結合@Qualifier注解一起使用。

@Resource裝配順序:
①如果同時指定了name和type,則從Spring上下文中找到唯一匹配的bean進行裝配,找不到則拋出異常。
②如果指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常。
③如果指定了type,則從上下文中找到類似匹配的唯一bean進行裝配,找不到或是找到多個,都會拋出異常。
④如果既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;如果沒有匹配,則回退為一個原始類型進行匹配,如果匹配則自動裝配。

因此, 如果一定要使用屬性注入, 可以使用 @Resource 代替 @Autowired 注解

@Autowired, @Qualifier, @Resource, 三者有何區(qū)別

  • @Autowired: 通過byType 方式進行裝配, 找不到或是找到多個,都會拋出異常。
  • @Qualifier: 如果想讓@Autowired 注入的Bean進行 byName裝配, 可以使用 @Qualifier 進行指定
  • @Resource :作用相當于@Autowired,只不過 @Resource 默認按照byName方式裝配, 如果沒有匹配, 則退回到 byType 方式進行裝配

參考文檔

為什么IDEA不推薦你使用@Autowired?

@Autowired和@Resource的區(qū)別是什么?

到此這篇關于為什么Spring和IDEA都不推薦使用 @Autowired 注解的文章就介紹到這了,更多相關Spring IDEA @Autowired 注解內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

最新評論