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

标签 java jakarta-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 个注入(inject)点:

  1. 我在 PingService 的构造函数中注入(inject) PingParams。

这是正确的吗?我的意思是,DI 容器无法知道超时并重试注入(inject) PingParams,除非您创建一些“Produces”注释方法,即使在这种情况下,仅仅为了创建一个对象就需要大量工作!但是,当然您需要创建多个,每个网络一个,您如何使用 DI 来做到这一点?

  1. 我在客户端中注入(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/

相关文章:

java - 操作表单中使用的数据类型

java - GlassFish SHA-256 摘要认证

c# - 当您还需要 "default"具体依赖项时,哪种依赖项注入(inject)更好的模式?

java - 控制 CastButton 的多个 View /Activity

java - 有没有办法使用 Hibernate 只从对象中获取更改的列?

Java将字节数组转换为十六进制字节数组

java - 编辑 LDAP 照片属性,spring-ldap InvalidAttributeValueException

Java HttpSession .getAttribute(字符串名称)

java - 如何在 Spring Boot 中使用带有构造函数注入(inject)的 YAML 属性?

c# - ASP.NET Web API 中处理程序和筛选器的依赖注入(inject)