我有两节课。
class A {
}
class B extends A {
}
并且在我的生产者类中,我这样声明。
@Produces A produceA(InjectionPoint ip) {
return new A();
}
void disposeA(A a) {
// empty
}
@Produces B produceB(InjectionPoint ip) {
return new B();
}
void disposeB(B b) {
// empty
}
而且Weld抱怨。
....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:
处置程序方法绑定到生产者方法或生产者字段,如果:
在您的特定情况下,您具有生产者方法produceB
,该方法创建一个类型将为{B, A, Object}
的bean。类型是从返回类型派生的,并将包含类型本身,所有超类和所有已实现的接口(as stated here in CDI spec)。
然后,您有两种处置方法,一种具有处置程序参数A
,另一种具有B
。您可以认为这些参数可以作为注入点,如果有帮助的话-您的produceB
生产者方法会创建一个适合这两个处理程序的bean,因此会产生歧义,因为Weld对于每个bean最多需要一个处理程序方法。
如果要详细了解类型安全解析的工作原理,请查看here。
关于如何“解决”这种情况,我可以从脑海中想出两种方法(可能有更多方法可以做到这一点:
@Typed
on the producer并将@Typed
的类型限制为仅produceB
,这也可以解决这种情况,但是bean将不再适合注入任何类型为B.class
的注入点。