為什么 Spring 構造器注入不需要 @Autowired 注解


Spring 三種注入方式

實習的時候看公司的項目代碼,發現一個有意思的事情,Service、Controller里面注入屬性時不是直接使用 @Autowired 進行注入的,而是選擇了直接使用構造器的方式,因此來總結一下Spring 常用的注入方式

屬性注入

其實這是我在學習 SpringBoot 時最常用的方式,直接在需要注入的屬性上添加 @Autowired 注解,簡單明了。

@RestController
public class TestController {
    @Autowired
    private TestService testService;
    @RequestMapping("/test")
    public String test() {
        return testService.test();
    }
}

使用 Autowired 注解,Spring 默認會在容器中找到對應類型的實例進行注入,當然,你也可以設置成根據屬性名來進行注入。

這種方式是最簡單的,但同時也是最不被推薦的。

setter 注入

簡而言之,就是利用對象的 setter 方法來進行注入

@Controller
public class TestController {
  private TestService testService;
   
  @Autowired
  public void setTestService(TestService testService) {
      this.testService = testService;
  }
}

這種方式在 Spring3.x 的時候是非常推薦的,不過我倒是沒咋見過它的使用。

構造器注入

這就是目前 Spring 最為推薦的注入方式,直接通過帶參構造方法來注入,我也是看公司項目代碼時才發現的,雖然學 Spring 的時候有提過,不過自己也一直沒用過,忘完了!

@Controller
public class TestController{
    private final TestService testService;
    public TestController(TestService testService){
        this.testService = testService;
    }
}

甚至於,在我們需要注入的對象非常多的時候,我們借助 Lombok 連構造方法都不用寫了

@RestController("xxx")
@RequestMapping("/x")
@AllArgsConstructor
public class AccountRelSiteController extends BaseController {
    private final XxxService xxxService;
    private final YyyService yyyService;
    private final ZzzService zzzService;
}

發現沒有,這里並沒有用到 @Autowired 這樣的注解,甚至沒出現任何能代表注入字樣的標記,而我們卻能正常的使用注入的對象,這是為什么?我不知道,所以趕緊去 StackOverFlow 看看有沒有和我一樣疑惑的老哥!

image-20211201201032673

還真有人和我一樣疑惑,不過他的猜測是 @AllArgsConstructor 注解注入了對象,當然這是不對的,因為我們不使用 Lombok 也能注入成功,在其它人的回答中我看見了 Spring 的官方文檔中的一段,其中給出了解釋:

As of Spring Framework 4.3, an @Autowired annotation on such a constructor is no longer necessary if the target bean only defines one constructor to begin with. However, if several constructors are available, at least one must be annotated to teach the container which one to use.

也就是說,這是 Spring 框架自身的一個特性,對於一個 SpringBean 來說,如果其只有一個構造方法,那么 Spring 會使用該構造方法並自動注入其所需要的全部依賴

詳情可見 Spring 4.3 的文檔中對 @Autowired 注解的解釋,beans-autowired-annotation


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM