Spring为什么建议构造器注入-Spring构造注入不需要加@Autowired?-《Java笔记》

admin 2025-10-19 04:17:18 编程 来源:ZONE.CI 全球网 0 阅读模式

Java Spring先看代码:

  1. @RestController
  2. @RequestMapping("/test")
  3. public class TestController {
  4. private final TestService testService;
  5. // @Autowired
  6. public TestController(TestService testService) {
  7. this.testService = testService;
  8. }
  9. @RequestMapping("/sayHello")
  10. public String sayHello() {
  11. return testService.sayHello();
  12. }
  13. }

@Autowired并不是必须的,不加也能注入成功,这是为什么?在 Spring4.x 中增加了新的特性:如果类只提供了一个带参数的构造方法,则不需要对对其内部的属性写 @Autowired 注解,Spring 会自动注入属性。

前言

因为业务关系也看了些同事写的代码,因为公司没有明确规定,有一部分人在注入依赖的时候使用了用Spring推荐的构造器注入的方式,一部分人使用了@Autowired的注解进行注入。因此,接下来总结归纳一下相关的情况,做一次回顾。用自己的话去说出来才算是真的掌握。

使用介绍

1、@Autowired注入

  1. @RestController
  2. @RequestMapping("/test")
  3. public class TestController {
  4. @Autowired
  5. private List<TestService> testServices;
  6. @Autowired
  7. private List<ChainAsbtract> chains;
  8. private ChainAsbtract target;
  9. }

2、构造器注入

Spring4.3+之后,constructor注入支持非显示注入方式。

  1. @RestController
  2. @RequestMapping("/test")
  3. public class TestController {
  4. // @Autowired
  5. private final List<TestService> testServices;
  6. // @Autowired
  7. private final List<ChainAsbtract> chains;
  8. // @Autowired
  9. public TestController(List<TestService> testServices, List<ChainAsbtract> chains) {
  10. this.testServices = testServices;
  11. this.chains = chains;
  12. }
  13. }

3、setter注入

  1. @RestController
  2. @RequestMapping("/test")
  3. public class TestController {
  4. // @Autowired
  5. private final List<TestService> testServices;
  6. // @Autowired
  7. private final List<ChainAsbtract> chains;
  8. @Autowired
  9. public void setTestServices(List<TestService> testServices){
  10. this.testServices = testServices;
  11. }
  12. @Autowired
  13. public void setTestServices(List<ChainAsbtract> chains){
  14. this.chains = chains;
  15. }
  16. }

事实上,spring在4.x版本后就推荐使用构造器的方式的来注入fileld

官方推荐理由

  • 单一职责:当使用构造函数注入的时候,会很容易发现参数是否过多,这个时候需要考虑这个类的职责是否过大,考虑拆分的问题;而当使用@Autowired注入field的时候,不容易发现问题
  • 依赖不可变:只有使用构造函数注入才能注入final
  • 依赖隐藏:使用依赖注入容器意味着类不再对依赖对象负责,获取依赖对象的职责就从类抽离出来,IOC容器会自动装备。这意味着它应该使用更明确清晰的公用接口方法或者构造器,这种方式就能很清晰的知道类需要什么和到底是使用setter还是构造器
  • 降低容器耦合度:依赖注入框架的核心思想之一是托管类不应依赖于所使用的DI容器。换句话说,它应该只是一个普通的POJO,只要将其传递给所有必需的依赖项,就可以独立地实例化。这样,可以在单元测试中实例化它,而无需启动IOC容器并单独进行测试(使用一个可以进行集成测试的容器)。如果没有容器耦合,则可以将该类用作托管或非托管类,甚至可以切换到新的DI框架。

另外,在使用构造器的使用能避免注入的依赖是空的情况。因为在bean的生命周期里面先执行的是bean的构造器,然后才给bean里面的属性赋值。

以太坊cppgolang区别 编程

以太坊cppgolang区别

以太坊是一种去中心化的开源平台,它采用智能合约技术,旨在构建和运行不受干扰的分布式应用程序。作为目前最受欢迎的区块链平台之一,以太坊提供了多种编程语言的支持,其
progolang 编程

progolang

Go语言(Golang)是由Google开发的一门静态类型编程语言。作为一名专业的Golang开发者,我深知这门语言的优势和特点。在本文中,我将介绍Golang
golangn个发送者 编程

golangn个发送者

Golang是一种开源的编程语言,由Google团队开发,旨在提高程序的并发性和简化软件开发过程。在Go语言中,有时需要向多个接收者发送信息。本文将介绍如何在G
golang技能图谱 编程

golang技能图谱

从互联网行业的快速发展到人工智能技术的日益成熟,各种编程语言也应运而生。而在这众多的编程语言中,Golang(即Go)作为一门强大且高效的开发语言备受关注。Go
评论:0   参与:  8