简体   繁体   English

如何注入 SPI 上下文中的接口

[英]How to Inject an Interface which is in the context of SPI

I have a Interface Hello.java which is implemented by 2 classes HelloImpl1.java and HelloImpl2.java我有一个接口 Hello.java,它由 2 个类 HelloImpl1.java 和 HelloImpl2.java 实现

I have declared HelloImpl1.java as part of META-INF/services.我已将 HelloImpl1.java 声明为 META-INF/services 的一部分。

Now, when I try to I Inject Hello class, it's failing saying ambiguity due to 2 implementations.现在,当我尝试注入 Hello class 时,由于 2 个实现,它没有说出歧义。

My question is when I already defined HelloImpl1.java as part of META-INF/services, why inject is not picking that class?我的问题是,当我已经将 HelloImpl1.java 定义为 META-INF/services 的一部分时,为什么注入不选择 class?

Kindly help me resolving the issue.请帮我解决这个问题。

I need to inject the Interface so that the Impl classes will be manged by CDI我需要注入接口,以便 CDI 管理 Impl 类

In CDI, a bean is identified by its types and qualifiers.在 CDI 中,bean 由其类型和限定符标识。 By default, types are derived from a transitive type closure of the bean class defining it (or a return type of a producer method/field defining the bean).默认情况下,类型派生自定义它的 bean class 的传递类型闭包(或定义 bean 的生产者方法/字段的返回类型)。

Therefore, in your case, there are two bean with following types:因此,在您的情况下,有两个具有以下类型的 bean:

  • {Hello, HelloImpl1}
  • {Hello, HelloImpl2}

You didn't use any qualifiers, which is why you see the ambiguity;您没有使用任何限定词,这就是您看到歧义的原因; when you @Inject Hello hello , CDI can see two eligible beans and cannot make a decision on which one is correct.当您@Inject Hello hello时,CDI 可以看到两个符合条件的 bean,但无法决定哪个是正确的。

I have declared HelloImpl1.java as part of META-INF/services.我已将 HelloImpl1.java 声明为 META-INF/services 的一部分。

I have no idea what you mean by that.我不知道你的意思。 Just declaring a bean there has no effect on CDI itself.仅仅声明一个 bean 对 CDI 本身没有影响。

The correct solution is to use CDI qualifiers, they are a natural fit to disambiguate two or more beans with equal types.正确的解决方案是使用 CDI 限定符,它们非常适合消除两个或多个具有相同类型的 bean 的歧义。 In your case, you didn't use any, so CDI automatically adds default qualifiers.在您的情况下,您没有使用任何,因此 CDI 会自动添加默认限定符。

Here is how you can declare your own qualifier:以下是您可以声明自己的限定符的方法:

@Qualifier
@Retention(RUNTIME)
@Target({ TYPE, FIELD, METHOD, PARAMETER })
public @interface MyQualifier {
}

You then annotate both, your bean declaration and any injection point where this is meant to be injected.然后,您对 bean 声明和任何要注入的注入点进行注释。

@Dependent // this is just an example, use any scope you need or have been using
@MyQualifier // specify qualifier of this bean
public class HelloImpl1 implements Hello {
// some very cool code
}

The following injection point is not ambiguous, because there will be only one bean with required type Hello and qualifier @MyQualifier .下面的注入点没有歧义,因为只有一个 bean 具有必需的类型Hello和限定符@MyQualifier

// declare the injection point with qualifier(s)
@Inject
@MyQualifier
Hello helloBean;

Finally, I'd recommend you read more about this in CDI specification.最后,我建议您在 CDI 规范中阅读更多相关内容。 Sections such as typesafe resolution or qualifiers are what you're looking for.诸如类型安全解析限定符之类的部分就是您要查找的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM