CDI:2 个具有不同资格的生产者
CDI: 2 Producers with different qualifiers
我有 2 个生产者方法,一个只有 1 个限定符,一个有 2 个限定符,一个来自第一个生产者,另一个来自:
@ApplicationScoped
public class MyProducer {
@Produces
@Qualifier1
MyBean produce1(InjectionPoint injectionPoint) {
...
}
@Produces
@Qualifier1
@Qualifier2
MyBean produce2(InjectionPoint injectionPoint) {
...
}
}
如果我尝试使用两个限定符 @Inject
MyBean,一切正常,调用 produce2
。但是当只用 @Qualifier1
注入 MyBean 时,我得到一个 AmbiguousResolutionException
。在我看来,只有当注入点具有两个限定符时才应调用 produce2
。为什么不是这样,我该怎么做才能让它发挥作用?
不幸的是我无法更改生产者方法 1,因为它在库中。基本计划是,如果注入点有我的附加限定符,则调用我自己的生产者,如果没有,则调用库中的那个。
我认为观察到的行为已在 CDI 2.0 ch.2.3.4“指定注入字段的限定符”中明确指定:
A bean may only be injected to an injection point if it has all the qualifiers of the injection point.
假设一个注入点:
@Inject @Qualifier1 MyBean myBean;
然后produce1
和produce1
生成的bean“具有注入点的所有限定符”,即@Qualifier1
,所以两者都有资格在那里注射,导致 AmbiguousResolutionException
.
事实上,规范给出的示例与 ch.2.3.6“重复限定符”中的问题完全相同。
那你能做什么?
首先,您真的需要用 @Qualifier1
来限定 produce2
吗?如果你没有充分的理由,只需从 produce2
中删除 @Qualifier1
即可完成 - 从库中使用 @Qualifier1
select MyBean
的注入点,使用 @Qualifier1
select MyBean
的注入点@Qualifier2
select 您的代码中的那个。 您的注入点不能同时具有 @Qualifier1
和 @Qualifier2
。
如果您仍想将 MyBean
从 produce2
注入到同时具有 @Qualifier1
和 @Qualifier2
的注入点,你仍然可以这样做 [免责声明:还没有真正尝试过,它可能需要调整]。这有点复杂:您必须编写一个可移植的扩展,这根本不是一件难事。简要实施要点:
producer2
必须注释 ONLY with @Qualifier2
- 在您的扩展中,观察
ProcessInjectionPoint
事件
- 如果
event.getInjectionPoint().getQualifiers()
同时包含@Qualifier1
和@Qualifier2
- 使用
event.configureInjectionPoint().qualifiers(...)
从限定符集中删除 @Qualifier1
。
效果是当 @Qualifier1
在运行时与 @Qualifier2
一起出现时,您将其删除。
我有 2 个生产者方法,一个只有 1 个限定符,一个有 2 个限定符,一个来自第一个生产者,另一个来自:
@ApplicationScoped
public class MyProducer {
@Produces
@Qualifier1
MyBean produce1(InjectionPoint injectionPoint) {
...
}
@Produces
@Qualifier1
@Qualifier2
MyBean produce2(InjectionPoint injectionPoint) {
...
}
}
如果我尝试使用两个限定符 @Inject
MyBean,一切正常,调用 produce2
。但是当只用 @Qualifier1
注入 MyBean 时,我得到一个 AmbiguousResolutionException
。在我看来,只有当注入点具有两个限定符时才应调用 produce2
。为什么不是这样,我该怎么做才能让它发挥作用?
不幸的是我无法更改生产者方法 1,因为它在库中。基本计划是,如果注入点有我的附加限定符,则调用我自己的生产者,如果没有,则调用库中的那个。
我认为观察到的行为已在 CDI 2.0 ch.2.3.4“指定注入字段的限定符”中明确指定:
A bean may only be injected to an injection point if it has all the qualifiers of the injection point.
假设一个注入点:
@Inject @Qualifier1 MyBean myBean;
然后produce1
和produce1
生成的bean“具有注入点的所有限定符”,即@Qualifier1
,所以两者都有资格在那里注射,导致 AmbiguousResolutionException
.
事实上,规范给出的示例与 ch.2.3.6“重复限定符”中的问题完全相同。
那你能做什么?
首先,您真的需要用 @Qualifier1
来限定 produce2
吗?如果你没有充分的理由,只需从 produce2
中删除 @Qualifier1
即可完成 - 从库中使用 @Qualifier1
select MyBean
的注入点,使用 @Qualifier1
select MyBean
的注入点@Qualifier2
select 您的代码中的那个。 您的注入点不能同时具有 @Qualifier1
和 @Qualifier2
。
如果您仍想将 MyBean
从 produce2
注入到同时具有 @Qualifier1
和 @Qualifier2
的注入点,你仍然可以这样做 [免责声明:还没有真正尝试过,它可能需要调整]。这有点复杂:您必须编写一个可移植的扩展,这根本不是一件难事。简要实施要点:
producer2
必须注释 ONLY with@Qualifier2
- 在您的扩展中,观察
ProcessInjectionPoint
事件 - 如果
event.getInjectionPoint().getQualifiers()
同时包含@Qualifier1
和@Qualifier2
- 使用
event.configureInjectionPoint().qualifiers(...)
从限定符集中删除@Qualifier1
。
- 使用
效果是当 @Qualifier1
在运行时与 @Qualifier2
一起出现时,您将其删除。