CDI 依赖注入可以是可选的吗?

Sha*_*arg 0 dependency-injection cdi

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

这是我尝试过的:

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;
}
Run Code Online (Sandbox Code Playgroud)

我收到一条错误消息:线程“main”org.jboss.weld.exceptions.DeploymentException 中的异常:WELD-001408 Unsatisfied dependencies for type [Optional] with qualifiers [@Default] at injection point [[BackedAnnotatedField] @Inject cafeteria.OmeletteMaker 。蔬菜]

Lai*_*son 6

在这个看似简单的问题中,潜藏着许多问题。我会尽量回答他们,牢记问题的精神。

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

第二,Optional没有特别之处。从 CDI 的角度来看, anOptional只是另一个 Java 对象,所以请参阅我上面的第一条语句。如果你有一些东西会产生一个Optional(比如一个生产者方法),那么它不能产生一个null Optional(除非,再次,生产被定义为在@Dependent范围内——如果你正在编写这样一个方法来创建Optional实例并返回null你肯定会去混淆您的用户)。如果您可以控制生产Optional实例,那么您可以按照自己喜欢的方式制作它们。

第三,如果您想测试以查看是否有托管 bean 或某种类型的 a 的生产者Fred,您可以,如对您的问题的评论之一所示,注入 aProvider<Fred>或 an Instance<Fred>。这些是由容器自动“制造”的:您不必编写任何特殊的东西来自己生产它们。AProvider<Fred>Fred实例的访问者,并且在get()调用其方法之前不会尝试获取实例。AnInstance是所有已知s 的aProvider和 an IterableFred并且可以另外告诉您是否 (a) 它是“不满意的”——根本没有 的生产者Fred——以及 (b) 它是“可解析的”——即,是否只有一个 的生产者Fred

第四,在您想查看是否存在某些东西的情况下,常见的习惯用法是注入Instance您想要的类型的参数化,然后检查其isResolvable()方法。如果返回true,那么您可以调用它的get()方法并相信它的返回值将是非null(假设它所做的事情不在@Dependent范围内)。

我希望这是有帮助的!