【问题标题】:CDI Inject dependencies from Injection Point owner来自注入点所有者的 CDI 注入依赖项
【发布时间】:2013-11-18 13:18:26
【问题描述】:

我有一个名为 Container 的类:

public class Container {

    @Inject
    ServiceA serviceA;

    @Inject
    ServiceB serviceB;

}

ServiceB 依赖于 serviceA:

public class ServiceB {

    @Inject 
    ServiceA serviceA;
}

在我的应用中可以有多个容器。现在,有什么技巧可以将这个 ServiceA 的实例注入到 ServiceB 中,它已经注入到与 ServiceB 相同的 Container 实例中?

【问题讨论】:

  • 不是这样吗?你尝试了什么?
  • @IanMcLaird:默认情况下,注入将在依赖范围内,每个可注入对象都有自己的依赖范围实例。至少,这是我的理解,这可能是错误的!

标签: java cdi


【解决方案1】:

将您的类注释为@ApplicationScoped@Singleton,这将确保您的应用程序中只有一个ServiceA 实例。此实例将在第一次注入此 bean 期间创建。

附:我更喜欢 Weld docs 中建议的 @ApplicationScoped,因为 @Singleton 没有可以在序列化期间使用问题的代理对象。

【讨论】:

  • 不幸的是,我需要将ServiceA 的不同实例注入到不同的Container 实例中,因此单例模式不适合我。我需要的是一种单个容器模式
  • 您可以使用每个 JVM 唯一的 EJB 单例(我不知道 CDI 是否同样适用),但恐怕没有其他方法可以实现您想要的。 .
【解决方案2】:

您可以创建具有自定义范围的 CDI 扩展 @ContainerScope "ContainerScopeExtension"...

如何制作自定义范围可以在这里阅读: https://rpestano.wordpress.com/2013/06/30/cdi-custom-scope/

这样一个 ContainerScopeExtension 的实现可能如下:

  1. 同一请求的每个容器实例都被记住在“容器缓存”中

  2. 在创建服务实例时。获取当前“生产者”请求的注入点。如果注入点是控制器,请检查是否已经为该容器生成了服务。 (例如在“每个容器缓存的服务”中)。否则创建一个新的服务实例并将其放入“服务缓存”并记住该服务实例的容器。

  3. 如果注入点是服务..则获取缓存的“父”服务实例,找到“父”服务的容器实例。然后您可以检查是否已经为找到的容器生成了服务实例...

  4. 等等……

【讨论】:

  • 但我认为整个应用程序也可能存在设计问题......
【解决方案3】:

您应该为您的对象定义一个@Singleton 范围。将@Singleton注解放到ServiceA类中

例如

@Singleton
public class ServiceA  { 

}

【讨论】:

    猜你喜欢
    • 2014-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多