为什么构造器注入不需要 @Autowired 或 @Resource 注解?
Spring有三种注入方式,分别是——属性注入、setter 注入、构造器注入
这种方式是最常用的,我们可以使用 @Autowired 或者是 @Resource 进行注入
- @RestController
- @RequestMapping("/shop")
- public class ShopController {
-
- @Resource
- public IShopService shopService;
-
- /**
- * 根据id查询商铺信息
- * @param id 商铺id
- * @return 商铺详情数据
- */
- @GetMapping("/{id}")
- public Result queryShopById(@PathVariable("id") Long id) {
- //return Result.ok(shopService.getById(id));
- return shopService.queryById(id);
- }
- }
使用方式是最简单,但是也是最不推荐的!要使用也是推荐使用 @Resource!
看看我写的这一篇文章!!!
这种方法是 Spring3.X 版本比较推荐的,但是我基本上没有见到有人用过!
- @Controller
- public class DemoController {
- private DemoService demoService;
-
- @Autowired
- public void setDemoService(DemoService demoService) {
- this.demoService = demoService;
- }
- }
用法大概就像上面的那样,在 set方法 上面加上注解即可。
这就是目前 Spring 最为推荐的注入方式,直接通过带参构造方法来注入。
这种方式我有在项目中有看到有人用过,但是也不是很多。
- // 部分代码
- @Component
- public class RedisIdWorker {
-
- private StringRedisTemplate stringRedisTemplate;
-
- public RedisIdWorker(StringRedisTemplate stringRedisTemplate) {
- this.stringRedisTemplate = stringRedisTemplate;
- }
- }
关于构造器注入Spring在文档里是这么说的
The Spring team generally advocates constructor injection as it enables one to implement application components as immutable objects and to ensure that required dependencies are not
null
. Furthermore constructor-injected components are always returned to client (calling) code in a fully initialized state.
这个构造器注入的方式啊,能够保证注入的组件不可变,并且确保需要的依赖不为空。此外,构造器注入的依赖总是能够在返回客户端(组件)代码的时候保证完全初始化的状态。
单一职责: 当使用构造函数注入的时候,你会很容易发现参数是否过多,这个时候需要考虑你这个类的职责是否过大,考虑拆分的问题;而当使用@Autowired注入field的时候,不容易发现问题
依赖不可变: 只有使用构造函数注入才能注入final
依赖隐藏:使用依赖注入容器意味着类不再对依赖对象负责,获取依赖对象的职责就从类抽离出来,IOC容器会帮你自动装备。这意味着它应该使用更明确清晰的公用接口方法或者构造器,这种方式就能很清晰的知道类需要什么和到底是使用setter还是构造器
降低容器耦合度: 依赖注入框架的核心思想之一是托管类不应依赖于所使用的DI容器。换句话说,它应该只是一个普通的POJO,只要您将其传递给所有必需的依赖项,就可以独立地实例化。这样,您可以在单元测试中实例化它,而无需启动IOC容器并单独进行测试(使用一个可以进行集成测试的容器)。如果没有容器耦合,则可以将该类用作托管或非托管类,甚至可以切换到新的DI框架。
Setter injection versus constructor injection and the use of @Required (spring.io)https://spring.io/blog/2007/07/11/setter-injection-versus-constructor-injection-and-the-use-of-required/Field Dependency Injection Considered Harmful | Vojtech Ruzicka's Programming Bloghttps://www.vojtechruzicka.com/field-dependency-injection-considered-harmful/
这是 Spring 框架自身的一个特性,对于一个 SpringBean 来说,如果其只有一个构造方法,那么 Spring 会使用该构造方法并自动注入其所需要的全部依赖!