如何处理继承类型的多种处理方法?
How can I handle multiple disposal methods for inherited types?
我有两个 class。
class A {
}
class B extends A {
}
在我的制作人中class我是这样声明的。
@Produces A produceA(InjectionPoint ip) {
return new A();
}
void disposeA(@Disposes A a) {
// empty
}
@Produces B produceB(InjectionPoint ip) {
return new B();
}
void disposeB(@Disposes B b) {
// empty
}
韦尔德抱怨。
....DefinitionException: WELD-000077: Cannot declare multiple disposal methods for this producer method.
Producer method: org.jboss.weld.bootstrap.BeanDeployer@41e68d87
Disposal methods:
- Disposer method [[BackedAnnotatedMethod] ....Producer.disposeA(@Disposes A)],
- Disposer method [[BackedAnnotatedMethod] ....Producer.disposeB(@Disposes B)]
这正常吗?我该如何解决?
这是一个类型安全的解决方案,它按预期工作。
根据规范,3.4.3. Disposer method resolution:
处理器方法绑定到生产者方法或生产者字段,如果:
- producer 方法或producer 字段由与disposer 方法相同的bean class声明,并且
- 根据类型安全解析中定义的类型安全解析规则(使用原始类型和参数化类型的可分配性),生产者方法或生产者字段可分配给处置参数。
在您的特定情况下,您有生产者方法 produceB
,它创建一个类型为 {B, A, Object}
的 bean。这些类型派生自 return 类型,并将包含类型本身、所有超级 classes 和所有已实现的接口 (as stated here in CDI spec).
然后您有两种处置方法,一种带有处置参数 A
,另一种带有 B
。如果有帮助,您可以将这些参数视为注入点 - 您的 produceB
生产者方法创建了一个适合这两个处理器的 bean,因此产生了歧义,因为 Weld 最多需要一个处理器方法用于每个 bean。
如果您想详细了解类型安全解析的具体工作原理,请查看 here。
至于如何"solve"这种情况,我可以想到两种方法(可能有更多方法可以做到这一点):
- 您可以在另一个 bean 中声明每个生产者 + 处理器。根据规范,disposer 需要在 producer 所在的同一个 bean 中声明,这样就可以消除这个问题。
- 您可以使用
@Typed
on the producer 并将 produceB
的类型限制为仅 B.class
这应该也可以解决这种情况,但该 bean 将不再有资格注入任何注入类型为 A
. 的点
我有两个 class。
class A {
}
class B extends A {
}
在我的制作人中class我是这样声明的。
@Produces A produceA(InjectionPoint ip) {
return new A();
}
void disposeA(@Disposes A a) {
// empty
}
@Produces B produceB(InjectionPoint ip) {
return new B();
}
void disposeB(@Disposes B b) {
// empty
}
韦尔德抱怨。
....DefinitionException: WELD-000077: Cannot declare multiple disposal methods for this producer method.
Producer method: org.jboss.weld.bootstrap.BeanDeployer@41e68d87
Disposal methods:
- Disposer method [[BackedAnnotatedMethod] ....Producer.disposeA(@Disposes A)],
- Disposer method [[BackedAnnotatedMethod] ....Producer.disposeB(@Disposes B)]
这正常吗?我该如何解决?
这是一个类型安全的解决方案,它按预期工作。 根据规范,3.4.3. Disposer method resolution:
处理器方法绑定到生产者方法或生产者字段,如果:
- producer 方法或producer 字段由与disposer 方法相同的bean class声明,并且
- 根据类型安全解析中定义的类型安全解析规则(使用原始类型和参数化类型的可分配性),生产者方法或生产者字段可分配给处置参数。
在您的特定情况下,您有生产者方法 produceB
,它创建一个类型为 {B, A, Object}
的 bean。这些类型派生自 return 类型,并将包含类型本身、所有超级 classes 和所有已实现的接口 (as stated here in CDI spec).
然后您有两种处置方法,一种带有处置参数 A
,另一种带有 B
。如果有帮助,您可以将这些参数视为注入点 - 您的 produceB
生产者方法创建了一个适合这两个处理器的 bean,因此产生了歧义,因为 Weld 最多需要一个处理器方法用于每个 bean。
如果您想详细了解类型安全解析的具体工作原理,请查看 here。
至于如何"solve"这种情况,我可以想到两种方法(可能有更多方法可以做到这一点):
- 您可以在另一个 bean 中声明每个生产者 + 处理器。根据规范,disposer 需要在 producer 所在的同一个 bean 中声明,这样就可以消除这个问题。
- 您可以使用
@Typed
on the producer 并将produceB
的类型限制为仅B.class
这应该也可以解决这种情况,但该 bean 将不再有资格注入任何注入类型为A
. 的点