【问题标题】:Can CDI dependency injection be optional?CDI 依赖注入可以是可选的吗?
【发布时间】:2020-04-28 17:47:31
【问题描述】:

在 Spring DI 中,将自动装配字段声明为 Optional 可以使客户端不向其注入任何值。这可能使用 Java EE 的 CDI 吗?我尝试了可选,但失败了。我想知道是否有我可以使用的等效机制。

这是我尝试过的:

public class OmeletteMaker implements EggMaker{
        public static void main(String[] args){
        WeldContainer container = new Weld().initialize();
        OmeletteMaker omeletteMaker = container.instance().select(OmeletteMaker.class).get();
    }

    @Inject
    Optional<Vegetable> vegetable;
}

我收到一条错误消息: 线程“main” org.jboss.weld.exceptions.DeploymentException 中的异常:WELD-001408 在注入点 [[BackedAnnotatedField] @Inject cafeteria.OmeletteMaker.vegetable] 带有限定符 [@Default] 的类型 [Optional] 的不满足依赖关系]

【问题讨论】:

  • 根据我的搜索, optional 应该可以工作(从未使用过)。但就像How to Ask 状态一样,发布您在minimal reproducible example 风格中尝试过的内容并发布您的搜索结果以及为什么它们没有帮助(发布“行为”、“不起作用”不是行为。还发布版本和实施信息
  • 谢谢,我添加了我尝试过的描述。
  • 无法快速找到链接,但据我记得应该是Instance&lt;Vegetable&gt;

标签: dependency-injection cdi


【解决方案1】:

在这个看似简单的问题中潜伏着许多问题。我将尝试在牢记问题的精神的情况下回答他们。

首先,作为一般规则,如果您 @InjectFred,则 Fred 不能是 null,除非 Fred@Dependent 范围内,即使这样,生产者方法或自定义 bean 也会必须明确写入返回null。有一些极端情况,但在所有现代 CDI 实现中,这是一个很好的经验法则。

其次,Optional 并不特别。从 CDI 的角度来看,Optional 只是另一个 Java 对象,所以请参阅上面的第一个语句。如果你有一些产生Optional 的东西(比如生产者方法),那么它不能产生null Optional (除非再次将生产定义为在@Dependent 范围内——如果你正在编写这种制作Optional 实例并返回null 的方法肯定会让你的用户感到困惑)。如果您可以控制生成 Optional 实例,那么您可以按照自己喜欢的方式制作它们。

第三,如果您想测试Fred 是否存在托管 bean 或某种生产者,您可以,正如您问题中的一个 cmet 所示,注入 Provider&lt;Fred&gt; 或一个Instance&lt;Fred&gt;。这些是由容器自动“制作”的:您不必编写任何特殊的东西来自己制作它们。 Provider&lt;Fred&gt;Fred 实例的访问器,并且在调用其 get() 方法之前不会尝试获取实例。 Instance 是所有已知 Freds 中的 ProviderIterable,并且还可以告诉您(a)它是否“不满意”——根本没有 Fred 的生产者——和(b ) 它是“可解析的”——即Fred 的生产者只有一位。

第四,如果你想看看有没有什么东西,常用的习惯是注入一个Instance,参数化为你想要的类型,然后检查它的isResolvable()方法。如果返回true,那么您可以调用它的get() 方法并相信它的返回值将不是null(假设它所做的东西不在@Dependent 范围内)。

希望对你有帮助!

【讨论】:

  • 对我在 StackOverflow 中找不到的内容的精彩总结。
  • " ,即使这样,生产者方法或自定义 bean 也必须显式编写以返回 null。存在边缘情况,但在所有现代 CDI 实现中,这是一个很好的经验法则记住。” 如果注入接口并且没有实现怎么办?
  • 感谢您的详尽回答。它既回答了我最初的问题,又涵盖了我不理解的其他主题!
  • @Kukeltje 如果你有 @Inject private Fred fred 并且 CDI 没有任何已知的实现 Fred 那么你将在启动时得到一个不满意的依赖错误。
  • @LiairdNelson:是的,我理解,但我说的是Instance 和_“它“不满意”——根本没有 Fred 的制作人——“_
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-22
  • 2011-02-28
  • 1970-01-01
相关资源
最近更新 更多