Java EE依赖注入什么时候使用?

时间:2013-12-29 15:21:43

标签: java java-ee dependency-injection cdi weld

我是新手,我想了解何时在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个注射点:

  1. 我在PingService的构造函数中注入了PingParams。
  2. 这是对的吗?我的意思是,DI容器无法知道超时并重试注入PingParams,除非你创建了一些“Produces”注释方法,即使在这种情况下,它只是为了创建一个对象而接受了一些工作!但是当然你需要创建几个,每个网络一个,你如何用DI做到这一点?

    1. 我在客户端注入了PingService。
    2. 似乎合法,但PingService依赖于PingParams,它将我们带到注入点1号。

      在我看来,使用DI的唯一合适方法是使用没有依赖关系(因此无用)的类,或使用非常简单的服务类,将所有依赖关系作为参数传递给服务方法。例如,一个接受ping方法中的ip和PingParams的PingService,这个类也没有依赖...

      我错过了什么吗?如何在这些“数据”类中使用DI,这些类只包含用于保存数据的字段(PingParams)?在这些情况下,是否应该避免DI?感谢

2 个答案:

答案 0 :(得分:2)

通常,您应该只对非数据类使用依赖注入。如果您的课程包含数据和非数据协作者,则可以使用assisted injection

你说的ping params确实应该绑定到应用程序启动时的实例并在必要时注入。对于你的例子,这确实是很多代码,但从长远来看,它可以在更大的项目中保持良好和干净。

总结一下:在应用程序启动时绑定PingParam(例如,作为Singleton),将其注入PingService,并在没有DI的情况下创建PingResult(正如您所做的那样)。

对于依赖注入最佳做法,我建议阅读Dependency Injection by Prasanna

答案 1 :(得分:0)

假设我们正在谈论CDI / Weld。假设您的PingParams类存储在数据库中,作为从某个表加载的配置。将它抽象出来是很有意义的,只需为PingParams类提供一个生成器方法,该类从DB读取数据并提供回这个数据元素。将数据对象用于此配置并为其提供生产者并不是一个坏主意。