Spring 依赖注入最佳实践?

2022-02-21 19:56:52 +08:00
 tinotino654321
Spring 官方文档里推荐的是用 Constructor 注入,可选依赖用 Setter 注入。
但是实际在项目里一般用哪种注入呢?
我工作没多久,见到的大部分都是用 Field 注入。
5215 次点击
所在节点    Java
50 条回复
chendy
2022-02-21 20:04:28 +08:00
final 字段 + 构造方法注入 + lombok 的 RequireArgsConstructor 注解
是不是最佳不知道,应该是字最少的
但是不能用来处理 RestTemplateBuilder 这样的特殊 bean
issakchill
2022-02-21 20:13:19 +08:00
我也是用 1 楼的方法
有个难处理的地方是这个类的子类要手写构造方法,不知道有没有更方便的做法?
sutra
2022-02-21 20:24:56 +08:00
Constractor 注入的话,可以把 field 标记为 final ,其它的则不行。
sutra
2022-02-21 20:30:19 +08:00
fpure
2022-02-21 20:41:41 +08:00
我不管,我就要用 @Autowire 属性注入
Bingchunmoli
2022-02-21 20:52:04 +08:00
官方推荐使用构造器,而旧项目和旧 Spring 用的比较多的是 autowired 和 resource , 都行,其实按推荐确实好点
7911364440
2022-02-21 20:54:11 +08:00
Constractor+1
Oktfolio
2022-02-21 20:55:07 +08:00
我是 Constractor + Setter
Oktfolio
2022-02-21 20:55:26 +08:00
@Oktfolio 啊这,复制了楼上的 typo
giiiiiithub
2022-02-21 21:19:24 +08:00
如果依赖是创建对象时必须的,肯定是构造器注入。否则应该用 setter 注入,最次是 field 。

以上是基于:1. 依赖是否必须在构造对象时提供,2. 方便 mock

但实际使用使用是另一回事。用 spring 那一套,即便用 filed 注入一般也没什么问题
tinotino654321
2022-02-21 21:35:26 +08:00
@sutra 实际上很少有依赖注入后会被修改的情况吧? final 其实也不是很重要?
sutra
2022-02-21 21:41:30 +08:00
@tinotino654321 final 的目的是为了防止被修改,也可以从语义角度表示,不可以修改。
sutra
2022-02-21 21:42:09 +08:00
@Oktfolio 我发完就发现我的 typo 了,然而 V2EX 不能改。哈哈哈……
tinotino654321
2022-02-21 21:42:12 +08:00
@giiiiiithub 我觉得 Field 注入最方便,但既是优点也是缺点。
优点是可以循环依赖,而且加依赖方便,不用改 Constructor 。
缺点是 Class 容易循环依赖,责任不清晰,并且依赖很多,容易形成屎山。
Mock 的话 Mockito 也可以 InjectMocks ,问题不是很大。
sutra
2022-02-21 21:48:01 +08:00
constructor 注入也能循环依赖,加 lazy 注解。
giiiiiithub
2022-02-21 22:02:08 +08:00
@tinotino654321 跟依赖循环没多大关系。主要是依赖应该不应该放在构造函数?能不能被 mock ? 你可以想象如果提供给外部使用,就需要问自己两个问题:1. 什么是必须的什么是可选的? 2. 什么是可以被修改的什么是不能被修改的?
liuxu
2022-02-21 22:15:08 +08:00
新版的 idea 不是推荐 contractor 里面用 @autowired 注入么
WispZhan
2022-02-21 22:59:42 +08:00
必然是按官方来,不然提 PR 都过不了 bot
honamx
2022-02-21 23:23:06 +08:00
@RequiredArgsConstructor + private final
appstore54321
2022-02-21 23:35:41 +08:00
构造函数注入,写单元测试时就知道了,这样最方便 mock 。直接 autowired 一个成员这怎么测。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/835484

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX