Spring的三种注入方式(为什么推荐构造器注入?)
为什么构造器注入不需要 @Autowired 或 @Resource 注解?
Spring的三种注入方式
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!
@Resource和@Autowired的区别
为什么尽量使用 @Resource?
看看我写的这一篇文章!!!
二、setter 注入
这种方法是 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框架。
具体可以看看Spring官网
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 Blog
https://www.vojtechruzicka.com/field-dependency-injection-considered-harmful/
为什么构造器注入不需要 @Autowired 或 @Resource 注解?
这是 Spring 框架自身的一个特性,对于一个 SpringBean 来说,如果其只有一个构造方法,那么 Spring 会使用该构造方法并自动注入其所需要的全部依赖!
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· spring官宣接入deepseek,真的太香了~