中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

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

發布時間:2022-04-02 15:49:26 來源:億速云 閱讀:528 作者:iii 欄目:開發技術

今天小編給大家分享一下Spring和IDEA為什么都不推薦使用@Autowired注解的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。

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

    背景

    做開發的同學可能都會發現, idea 在我們經常使用的@Autowired 注解上添加了警告
    警告內容是: Field injection is not recommended, 譯為: 不推薦使用屬性注入

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

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

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

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

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

    原因

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

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

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

    @RestController
    public class AppointmentNumberConfigurationController {
    
        @Autowired
        private AppointmentNumberConfigurationService numberConfigurationService;
    }

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

    @RestController
    public class AppointmentNumberConfigurationController {
    
    
        private AppointmentNumberConfigurationService numberConfigurationService;
    
        @Autowired
        public void setNumberConfigurationService(AppointmentNumberConfigurationService numberConfigurationService) {
            this.numberConfigurationService = numberConfigurationService;
    }

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

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

    三種方式對比如下

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

    使用屬性注入可能會出現的問題

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

    根據構造器注入的,相當于當容器調用帶有一組參數的類構造函數時,基于構造函數的 DI 就完成了,
    其中每個參數代表一個對其他類的依賴。基于構造方法為屬性賦值,容器通過調用類的構造方法將其進行依賴注入

    思考

    為什么推薦使用@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, 三者有何區別

    • @Autowired: 通過byType 方式進行裝配, 找不到或是找到多個,都會拋出異常。

    • @Qualifier: 如果想讓@Autowired 注入的Bean進行 byName裝配, 可以使用 @Qualifier 進行指定

    • @Resource :作用相當于@Autowired,只不過 @Resource 默認按照byName方式裝配, 如果沒有匹配, 則退回到 byType 方式進行裝配

    以上就是“Spring和IDEA為什么都不推薦使用@Autowired注解”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。

    向AI問一下細節

    免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

    AI

    宜良县| 水城县| 青阳县| 澄迈县| 台东县| 黑河市| 丰镇市| 尼玛县| 邳州市| 萨嘎县| 张家口市| 眉山市| 陵川县| 嵩明县| 高阳县| 荥阳市| 怀集县| 会泽县| 稻城县| 望谟县| 尉犁县| 米脂县| 思南县| 金川县| 余干县| 确山县| 大冶市| 许昌市| 绥滨县| 伊宁县| 九龙城区| 囊谦县| 大邑县| 胶南市| 乐亭县| 子洲县| 桐柏县| 哈巴河县| 华容县| 英超| 巢湖市|