<kbd id="5sdj3"></kbd>
<th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>

    公司禁止在 SpringBoot 中使用 @Autowired 注解,為什么?

    共 5324字,需瀏覽 11分鐘

     ·

    2024-07-15 12:20

    大家好,我是胖虎,首先大家分享兩個(gè)產(chǎn)品

    無需魔法,國內(nèi)可直接使用官方ChatGPT-4(Plus)、ChatGPT-4o!

    Java八股文面試小程序!

    Spring 官方已不推薦使用 Autowired 字段/屬性注入 bean,一些大公司的新項(xiàng)目也明令禁止使用了。

    說明

    最近公司升級(jí)框架,由原來的 spring framework 3.0 升級(jí)到 5.0,然后寫代碼的時(shí)候突然發(fā)現(xiàn) idea 在屬性注入的 @Autowired 注解上給出警告提示,就像下面這樣的,也是挺懵逼的,畢竟這么寫也很多年了。

    Field injection is not recommended?

    查閱了相關(guān)文檔了解了一下,原來這個(gè)提示是 spring framework 4.0 以后開始出現(xiàn)的,spring 4.0 開始就不推薦使用屬性注入,改為推薦構(gòu)造器注入和 setter 注入。

    下面將展示了 spring 框架可以使用的不同類型的依賴注入,以及每種依賴注入的適用情況。

    依賴注入的類型

    盡管針對(duì) spring framework 5.1.3 的文檔只定義了兩種主要的依賴注入類型,但實(shí)際上有三種:

    • 基于構(gòu)造器的依賴注入

    • 基于 setter 的依賴注入

    • 基于字段的依賴注入

    其中基于字段的依賴注入被廣泛使用,但是 idea 或者其他靜態(tài)代碼分析工具會(huì)給出提示信息,不推薦使用。

    甚至可以在一些 Spring 官方指南中看到這種注入方法:

    2.1 基于構(gòu)造器的依賴注入

    在基于構(gòu)造函數(shù)的依賴注入中,類構(gòu)造函數(shù)被標(biāo)注為 @Autowired,并包含了許多與要注入的對(duì)象相關(guān)的參數(shù)。

    @Component
    public class ConstructorBasedInjection {
        
        private final InjectedBean injectedBean;
        
        @Autowired    
        public ConstructorBasedInjection(InjectedBean injectedBean) {        
            this.injectedBean = injectedBean;    
        }
    }

    然后在spring官方文檔中,@Autowired 注解也是可以省去的。

    public class SimpleMovieLister {

        // the SimpleMovieLister has a dependency on a MovieFinder
        private MovieFinder movieFinder;

        // a constructor so that the Spring container can inject a MovieFinder
        public SimpleMovieLister(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }

        // business logic that actually uses the injected MovieFinder is omitted...
    }

    基于構(gòu)造函數(shù)注入的主要優(yōu)點(diǎn)是可以將需要注入的字段聲明為 final, 使得它們會(huì)在類實(shí)例化期間被初始化,這對(duì)于所需的依賴項(xiàng)很方便。

    2.2 基于 Setter 的依賴注入

    在基于 setter 的依賴注入中,setter 方法被標(biāo)注為 @Autowired。一旦使用無參數(shù)構(gòu)造函數(shù)或無參數(shù)靜態(tài)工廠方法實(shí)例化 Bean,為了注入 Bean 的依賴項(xiàng),Spring 容器將調(diào)用這些 setter 方法。

    @Component
    public class SetterBasedInjection {

        private InjectedBean injectedBean;

        @Autowired
        public void setInjectedBean(InjectedBean injectedBean) {
            this.injectedBean = injectedBean;
        }
    }

    和基于構(gòu)造器的依賴注入一樣,在官方文檔中,基于 Setter 的依賴注入中的 @Autowired 也可以省去。

    public class SimpleMovieLister {

        // the SimpleMovieLister has a dependency on the MovieFinder
        private MovieFinder movieFinder;

        // a setter method so that the Spring container can inject a MovieFinder
        public void setMovieFinder(MovieFinder movieFinder) {
            this.movieFinder = movieFinder;
        }

        // business logic that actually uses the injected MovieFinder is omitted...
    }

    2.3 基于屬性的依賴注入

    在基于屬性的依賴注入中,字段/屬性被標(biāo)注為 @Autowired。一旦類被實(shí)例化,Spring 容器將設(shè)置這些字段。

    @Component
    public class FieldBasedInjection {
        @Autowired
        private InjectedBean injectedBean;
    }

    正如所看到的,這是依賴注入最干凈的方法,因?yàn)樗苊饬颂砑訕影宕a,并且不需要聲明類的構(gòu)造函數(shù)。代碼看起來很干凈簡潔,但是正如代碼檢查器已經(jīng)向我們暗示的那樣,這種方法有一些缺點(diǎn)。

    基于字段的依賴注入缺陷

    3.1 不允許聲明不可變域

    基于字段的依賴注入在聲明為 final/immutable 的字段上不起作用,因?yàn)檫@些字段必須在類實(shí)例化時(shí)實(shí)例化。聲明不可變依賴項(xiàng)的唯一方法是使用基于構(gòu)造器的依賴注入。

    3.2 容易違反單一職責(zé)設(shè)計(jì)原則

    在面向?qū)ο蟮木幊讨?,五大設(shè)計(jì)原則SOLID被廣泛應(yīng)用,(國內(nèi)一般為六大設(shè)計(jì)原則),用以提高代碼的重用性,可讀性,可靠性和可維護(hù)性。

    S 在 SOLID 中代表單一職責(zé)原則,即一個(gè)類應(yīng)該只負(fù)責(zé)一項(xiàng)職責(zé),這個(gè)類提供的所有服務(wù)都應(yīng)該只為它負(fù)責(zé)的職責(zé)服務(wù)。

    使用基于字段的依賴注入,高頻使用的類隨著時(shí)間的推移,我們會(huì)在類中逐漸添加越來越多的依賴項(xiàng),我們用著很爽,很容易忽略類中的依賴已經(jīng)太多了。但是如果使用基于構(gòu)造函數(shù)的依賴注入,隨著越來越多的依賴項(xiàng)被添加到類中,構(gòu)造函數(shù)會(huì)變得越來越大,我們一眼就可以察覺到哪里不對(duì)勁。

    有一個(gè)有超過10個(gè)參數(shù)的構(gòu)造函數(shù)是一個(gè)明顯的信號(hào),表明類已經(jīng)轉(zhuǎn)變一個(gè)大而全的功能合集,需要將類分割成更小、更容易維護(hù)的塊。

    因此,盡管屬性注入并不是破壞單一責(zé)任原則的直接原因,但它隱藏了信號(hào),使我們很容易忽略這些信號(hào)。

    3.3 與依賴注入容器緊密耦合

    使用基于字段的依賴注入的主要原因是為了避免 getter 和 setter 的樣板代碼或?yàn)轭悇?chuàng)建構(gòu)造函數(shù)。最后,這意味著設(shè)置這些字段的唯一方法是通過Spring容器實(shí)例化類并使用反射注入它們,否則字段將保持 null。

    依賴注入設(shè)計(jì)模式將類依賴項(xiàng)的創(chuàng)建與類本身分離開來,并將此責(zé)任轉(zhuǎn)移到類注入容器,從而允許程序設(shè)計(jì)解耦,并遵循單一職責(zé)和依賴項(xiàng)倒置原則(同樣可靠)。因此,通過自動(dòng)裝配(autowiring)字段來實(shí)現(xiàn)的類的解耦,最終會(huì)因?yàn)樵俅闻c類注入容器(在本例中是 Spring)耦合而丟失,從而使類在Spring容器之外變得無用。

    這意味著,如果您想在應(yīng)用程序容器之外使用您的類,例如用于單元測試,您將被迫使用 Spring 容器來實(shí)例化您的類,因?yàn)闆]有其他可能的方法(除了反射)來設(shè)置自動(dòng)裝配字段。

    3.4 隱藏依賴關(guān)系

    在使用依賴注入時(shí),受影響的類應(yīng)該使用公共接口清楚地公開這些依賴項(xiàng),方法是在構(gòu)造函數(shù)中公開所需的依賴項(xiàng),或者使用方法(setter)公開可選的依賴項(xiàng)。當(dāng)使用基于字段的依賴注入時(shí),實(shí)質(zhì)上是將這些依賴對(duì)外隱藏了。

    總結(jié)

    我們已經(jīng)看到,基于字段的注入應(yīng)該盡可能地避免,因?yàn)樗性S多缺點(diǎn),無論它看起來多么優(yōu)雅。推薦的方法是使用基于構(gòu)造函數(shù)和基于setter的依賴注入。對(duì)于必需的依賴,建議使用基于構(gòu)造函數(shù)的注入,設(shè)置它們?yōu)椴豢勺兊?,并防止它們?yōu)?null。對(duì)于可選的依賴項(xiàng),建議使用基于 setter 的注入。

    參考文檔

    Field injection is not recommended – Spring IOC by Marc Nuri

    spring官方文檔 1.4. Dependencies

    來源:juejin.cn/post/7275009721760432168
        

    瀏覽 791
    1點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)
    評(píng)論
    圖片
    表情
    推薦
    1點(diǎn)贊
    評(píng)論
    收藏
    分享

    手機(jī)掃一掃分享

    分享
    舉報(bào)

    <kbd id="5sdj3"></kbd>
    <th id="5sdj3"></th>

  • <dd id="5sdj3"><form id="5sdj3"></form></dd>
    <td id="5sdj3"><form id="5sdj3"><big id="5sdj3"></big></form></td><del id="5sdj3"></del>

  • <dd id="5sdj3"></dd>
    <dfn id="5sdj3"></dfn>
  • <th id="5sdj3"></th>
    <tfoot id="5sdj3"><menuitem id="5sdj3"></menuitem></tfoot>

  • <td id="5sdj3"><form id="5sdj3"><menu id="5sdj3"></menu></form></td>
  • <kbd id="5sdj3"><form id="5sdj3"></form></kbd>
    日韩性爱在线电影网 | 国产成人亚洲一区二区三区 | 久久久久久久人妻丝袜 | 影音先锋av黄色 影音先锋成人网址 | 无码人妻丰满熟妇精品 |