【发布时间】:2018-04-22 10:05:18
【问题描述】:
我使用的代码中的一些控制器和服务有很多 @Autowired 依赖项。自动装配有两种流行的方法 - Autowire 字段和 Autowire 构造函数。
在第一种情况下,您复制注释 @Autowired。
public class SomeController {
@Autowired
private SomeService1 someService1;
@Autowired
private SomeService2 someService2;
@Autowired
private SomeService3 someService3;
}
在第二种情况下,您创建了一个丑陋且无用的构造函数。
public class SomeController {
private final SomeService1 someService1;
private final SomeService2 someService2;
private final SomeService3 someService3;
@Autowired
public SomeController(SomeService1 someService1,
SomeService2 someService2,
SomeService3 someService3) {
this.someService1 = someService1;
this.someService2 = someService2;
this.someService3 = someService3;
}
}
当您有很多应该自动装配的字段时,情况会变得更糟。我同意很多依赖项通常标志着一个糟糕的设计,但这不是我的问题。我想使用@AutowireAll 之类的东西来避免代码重复,该注释将自动装配所有可能自动装配的字段。我搜索了它,但找不到。可能的代码如下所示
@AutowireAll
public class SomeController {
private SomeService1 someService1;
private SomeService2 someService2;
private SomeService3 someService3;
}
如何避免代码重复?
【问题讨论】:
-
这会让你遇到 Jigsaw 对反射的限制(至少,只要你不禁用它们)。在我看来,“丑陋的构造函数”是更清洁的解决方案。
-
不,我不认为这是可能的。 @Autowired 在您的领域没有违反 DRY。它相当清楚地定义了您要为 DI 考虑哪些字段。例如,您不会说使用公共/私有访问修饰符违反了 DRY。顺便说一句,字段注入是一种不好的做法,建议使用构造函数注入。同意长构造函数问题,但也正如您所说,这是代码的味道。
-
不知道 SO 上禁止使用词库。我们都使用它们。使用库而不发明轮子并不丢人。
-
如果有人感兴趣,有一个使用 Lombok
AllArgsConstructor的解决方案。所以你不需要构造函数,也不需要@Autowired注释,只需要字段,它们可以是最终的。 -
并不是说 Word 库是题外话——我们所有人一直都在使用库,适用于所有编程语言。但是,根据help center,询问 what 库使用“对于 Stack Overflow 来说是无关紧要的,因为它们往往会吸引固执己见的答案和垃圾邮件”。
标签: java spring spring-boot dry