<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          CTO 說了,用錯 @Autowired 和 @Resource 的人可以領盒飯了

          共 6358字,需瀏覽 13分鐘

           ·

          2021-04-08 23:45

          往期熱門文章:

          1、往期精選優(yōu)秀博文都在這里了!
          2、如何解決MySQL order by limit語句的分頁數(shù)據(jù)重復問題?
          3、Java中八個潛在的內(nèi)存泄露風險,你知道幾個?
          4、為什么你996猝死,你老板007都沒事?
          5、美團面試題:String s = new String("111")會創(chuàng)建幾個對象?

          來源:https://juejin.cn/post/6844904064212271117

          介紹

          今天使用Idea寫代碼的時候,看到之前的項目中顯示有warning的提示,去看了下,是如下代碼?

          @Autowire
          private JdbcTemplate jdbcTemplate;

          提示的警告信息

          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工作組的建議,大致翻譯一下:

          屬性字段注入的方式不推薦,檢查到的問題是:Spring團隊建議:"始終在bean中使用基于構(gòu)造函數(shù)的依賴項注入,始終對強制性依賴項使用斷言"

          如圖

          Field注入警告

          注入方式

          雖然當前有關Spring Framework(5.0.3)的文檔僅定義了兩種主要的注入類型,但實際上有三種:

          基于構(gòu)造函數(shù)的依賴注入

          public class UserServiceImpl implents UserService{
              private UserDao userDao;
              
              @Autowire
              public UserServiceImpl(UserDao userDao){
                  this.userDao = userDao;
              }
          }

          基于Setter的依賴注入

          public class UserServiceImpl implents UserService{
               private UserDao userDao;
               
               @Autowire
               public serUserDao(UserDao userDao){
                   this.userDao = userDao;
               }
           }

          基于字段的依賴注入

          public class UserServiceImpl implents UserService{
               @Autowire
               private UserDao userDao;
           }

          基于字段的依賴注入方式會在Idea當中吃到黃牌警告,但是這種使用方式使用的也最廣泛,因為簡潔方便.您甚至可以在一些Spring指南中看到這種注入方法,盡管在文檔中不建議這樣做.(有點執(zhí)法犯法的感覺)

          如圖

          Spring自己的文檔

          基于字段的依賴注入缺點

          對于有final修飾的變量不好使

          Spring的IOC對待屬性的注入使用的是set形式,但是final類型的變量在調(diào)用class的構(gòu)造函數(shù)的這個過程當中就得初始化完成,這個是基于字段的依賴注入做不到的地方.只能使用基于構(gòu)造函數(shù)的依賴注入的方式

          掩蓋單一職責的設計思想

          我們都知道在OOP的設計當中有一個單一職責思想,如果你采用的是基于構(gòu)造函數(shù)的依賴注入的方式來使用Spring的IOC的時候,當你注入的太多的時候,這個構(gòu)造方法的參數(shù)就會很龐大,類似于下面.

          當你看到這個類的構(gòu)造方法那么多參數(shù)的時候,你自然而然的會想一下:這個類是不是違反了單一職責思想?.但是使用基于字段的依賴注入不會讓你察覺,你會很沉浸在@Autowire當中

          public class VerifyServiceImpl implents VerifyService{
              
            private AccountService accountService;
            private UserService userService;
            private IDService idService;
            private RoleService roleService;
            private PermissionService permissionService;
            private EnterpriseService enterpriseService;
            private EmployeeService employService;
            private TaskService taskService;
            private RedisService redisService;
            private MQService mqService;

            public SystemLogDto(AccountService accountService, 
                                UserService userService, 
                                IDService idService, 
                                RoleService roleService, 
                                PermissionService permissionService, 
                                EnterpriseService enterpriseService, 
                                EmployeeService employService, 
                                TaskService taskService, 
                                RedisService redisService, 
                                MQService mqService)
           
          {
                this.accountService = accountService;
                this.userService = userService;
                this.idService = idService;
                this.roleService = roleService;
                this.permissionService = permissionService;
                this.enterpriseService = enterpriseService;
                this.employService = employService;
                this.taskService = taskService;
                this.redisService = redisService;
                this.mqService = mqService;
            }
          }

          與Spring的IOC機制緊密耦合

          當你使用基于字段的依賴注入方式的時候,確實可以省略構(gòu)造方法和setter這些個模板類型的方法,但是,你把控制權(quán)全給Spring的IOC了,別的類想重新設置下你的某個注入屬性,沒法處理(當然反射可以做到).

          本身Spring的目的就是解藕和依賴反轉(zhuǎn),結(jié)果通過再次與類注入器(在本例中為Spring)耦合,失去了通過自動裝配類字段而實現(xiàn)的對類的解耦,從而使類在Spring容器之外無效.

          隱藏依賴性

          當你使用Spring的IOC的時候,被注入的類應當使用一些public類型(構(gòu)造方法,和setter類型方法)的方法來向外界表達:我需要什么依賴.但是基于字段的依賴注入的方式,基本都是private形式的,private把屬性都給封印到class當中了.

          無法對注入的屬性進行安檢

          基于字段的依賴注入方式,你在程序啟動的時候無法拿到這個類,只有在真正的業(yè)務使用的時候才會拿到,一般情況下,這個注入的都是非null的,萬一要是null怎么辦,在業(yè)務處理的時候錯誤才爆出來,時間有點晚了,如果在啟動的時候就暴露出來,那么bug就可以很快得到修復(當然你可以加注解校驗).

          如果你想在屬性注入的時候,想根據(jù)這個注入的對象操作點東西,你無法辦到.我碰到過的例子:一些配置信息啊,有些人總是會配錯誤,等到了自己測試業(yè)務階段才知道配錯了,例如線程初始個數(shù)不小心配置成了3000,機器真的是狂叫啊!這個時候就需要再某些Value注入的時候做一個檢測機制.

          結(jié)論

          通過上面,我們可以看到,基于字段的依賴注入方式有很多缺點,我們應當避免使用基于字段的依賴注入.推薦的方法是使用基于構(gòu)造函數(shù)基于setter的依賴注入.對于必需的依賴項,建議使用基于構(gòu)造函數(shù)的注入,以使它們成為不可變的,并防止它們?yōu)閚ull。對于可選的依賴項,建議使用基于Setter的注入

          后記

          翻譯自field-injection-is-not-recommended,加入了自己的白話理解!

          往期熱門文章:

          1、歷史文章分類導讀列表!精選優(yōu)秀博文都在這里了!》

          2、一個牛逼的 多級緩存 實現(xiàn)方案!
          3、阿里一面:如何保障消息100%投遞成功、消息冪等性?
          4、GitHub 熱榜:被網(wǎng)友瘋狂惡搞的「螞蟻呀嘿」項目終于開源了!
          5、記??!看小電影前一定要檢查一下域名是不是 HTTPS 的,不然....
          6、拿到年終獎后馬上辭職,厚道嗎?
          7、Redis 內(nèi)存滿了怎么辦?
          8、在 IDE 中玩轉(zhuǎn) GitHub
          9、死磕18個Java8日期處理,工作必用!
          10、把我坑慘的一個MySQL雙引號!

          瀏覽 48
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  男人的天堂地址 | 亚洲黄色自拍 | 日本久久大香蕉 | 人人操碰 | 国产免费又粗又大又硬又爽视频 |