我对此很陌生,我想了解什么时候适合在 Java 中使用 DI。假设我需要使用不同的 ping 参数来 ping 不同的网络:
PingParams 类:
public class PingParams {
int timeout;
int retries;
}
PingResult 类:
public class PingResult {
int ttl;
boolean available;
}
PingService 类:
public class PingService {
private PingParams pingParams;
@Inject
public PingService(PingParams pingParams) {
this.pingParams = pingParams;
}
public PingResult ping(String ip) {
// ping using timeout and retries from pingParams
return new PingResult();
}
}
客户端:
public class Client {
@Inject
PingService pingService;
private List<PingResult> doPing() {
List<PingResult> ret = new ArrayList<>();
String[] ips = new String[] {"127.0.0.1","127.0.0.2"};
for (String ip : ips) {
PingResult pr = pingService.ping(ip);
ret.add(pr);
}
return ret;
}
public static void main(String[] args) {
List<PingResult> prs = new Client().doPing();
System.out.println(prs);
}
}
我有 2 个注入(inject)点:
- 我在 PingService 的构造函数中注入(inject) PingParams。
这是正确的吗?我的意思是,DI 容器无法知道超时并重试注入(inject) PingParams,除非您创建一些“Produces”注释方法,即使在这种情况下,仅仅为了创建一个对象就需要大量工作!但是,当然您需要创建多个,每个网络一个,您如何使用 DI 来做到这一点?
- 我在客户端中注入(inject) PingService。
看起来合法,但 PingService 依赖于 PingParams,这将我们带到注入(inject)点 1。
在我看来,使用 DI 的唯一合适方法是使用没有依赖项(因此无用)的类,或者使用非常简单的服务类,在其中将所有依赖项作为参数传递给服务方法。例如,在 ping 方法中接受 ip 和 PingParams 的 PingService,同样,此类将没有依赖项...
我错过了什么吗?如何将 DI 与这些“数据”类一起使用,这些类仅包含用于保存数据的字段 (PingParams)?在这些情况下应该避免 DI 吗?谢谢
最佳答案
一般来说,您应该只对非数据类使用依赖注入(inject)。如果您的类同时包含数据和非数据协作者,则可以使用 assisted injection .
您谈论的 ping 参数确实应该在应用程序启动时绑定(bind)到一个实例,并在必要时注入(inject)。对于您的示例来说,这确实是很多代码,但从长远来看,它可以在更大的项目中保持良好和干净的状态。
总结一下:在应用程序启动时绑定(bind) PingParam(例如作为 Singleton),将其注入(inject)到 PingService 中,并在没有 DI 的情况下创建 PingResult(正如您所做的那样)。
对于依赖注入(inject)最佳实践,我建议阅读 Dependency Injection by Prasanna
关于Java EE 依赖注入(inject)什么时候使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20826671/