Jakarta ee 限定符作为接口的扩展

Jakarta ee 限定符作为接口的扩展,jakarta-ee,ejb,cdi,Jakarta Ee,Ejb,Cdi,我在EJB和CDI方面没有经验,目前我正在努力理解它们的一些基本原理以及如何使用它们。特别是我想掌握限定符的目的和用法,我已经阅读了。我无法完全理解限定符如何作为接口的扩展。以指南中的示例和语句为出发点:“限定符就像接口的扩展。它不会创建对任何特定实现的直接依赖关系。@Asynchronous PaymentProcessor!”可能有多个替代实现,我假设可以这样做: @Asynchronous public class AsynchronousPaymentProcessor impleme

我在
EJB
CDI
方面没有经验,目前我正在努力理解它们的一些基本原理以及如何使用它们。特别是我想掌握限定符的目的和用法,我已经阅读了。我无法完全理解
限定符如何作为接口的扩展。以指南中的示例和语句为出发点:“限定符就像接口的扩展。它不会创建对任何特定实现的直接依赖关系。@Asynchronous PaymentProcessor!”可能有多个替代实现,我假设可以这样做:

@Asynchronous

public class AsynchronousPaymentProcessor implements PaymentProcessor {

   public void process(Payment payment) { ... }

} 

然后他们尝试注入如下内容:

@Inject @Asynchronous PaymentProcessor asyncPaymentProcessor;
在这种情况下,如何确定注入了哪个bean,因为这两个bean都使用相同的
限定符
?或者一个限定符的多个实现是否只涉及
备选方案

更新完成:


我也读了相关的问题。我想要的是一个没有太长描述的答案:既然我可以注入实现接口的类型类,那么注入接口类型除了实现松耦合之外还有什么好处?如果我用2个
@Asynchronous
实现尝试上面的代码,并收到一个异常,那么我推断它(多个实现)只能通过其他方法实现。我说得对吗?

规范第5.2节:

如果满足以下条件,则bean可分配给给定的注入点:

  • 该bean具有与所需类型匹配的bean类型。为此,在java.lang中,原语类型被视为与其对应的包装器类型相匹配,而数组类型仅在其元素类型相同时才被视为匹配。如第5.2.3节“原始类型和参数化类型的可分配性”或第8.3.1节“代理注入点的原始类型和参数化类型的可分配性”所定义,如果参数化类型和原始类型相同或bean类型可分配给所需类型,则认为参数化类型和原始类型匹配

  • bean具有所有必需的限定符。如果没有显式指定所需的限定符,则容器将采用所需的限定符@Default。如果bean的每个成员(A)具有相同类型的限定符,并且(b)具有相同的注释成员值(未注释@javax.enterprise.util.Nonbinding),则bean具有必需的限定符


简而言之,容器查找满足注入点类型的所有bean,然后注入一个bean,该bean的限定符集与注入点上的限定符集匹配。如果没有匹配的bean,您会得到不满意的依赖项,或者如果有多个bean匹配,您会得到明确的依赖项。

请查看此答案,特别是标题为“是否需要限定符?”的部分。此外,您的示例没有正确遵循指南,在这种情况下,您会得到明确的USDependecException。在指南中,他们有两个限定符,
@Synchronous
@Asynchronous
。或者在两个实现中使用
@Asynchronous
的示例中,他们添加了额外的限定符。这非常接近。在CDI(实际上是JSR330)中,限定符和对象的类型组合为注入点的完整类型。限定符将进一步的元类型信息添加到注入点。@LightGuard因此,您希望我重新表述容器只是将注入点的类型与bean的类型相匹配,因为限定符是为了注入而对这两种类型进行补充,而不是说容器首先匹配类型,然后是限定符,或者是其他东西?容器采用哪种方式更像是一个实现细节。如果这三个实现都以相同的方式进行,那么这只是巧合,规范并不要求它以特定的方式进行。只需进一步澄清。@LightGuard你是对的。然而,我这样说并不是因为它是如何实现的,而是要指出,尽管任何特定的bean都可以实现多个接口,但一个接口就足够匹配(我想这是显而易见的原因),而所有(所有限定符的集合)必须完全匹配。
@Inject @Asynchronous PaymentProcessor asyncPaymentProcessor;