java - 如何处理继承类型的多种处理方法?

标签 java cdi weld weld2 weld-junit5

我有两个类。

class A {
}

class B extends A {
}

在我的生产者类中,我是这样声明的。

@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
}

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 :

如果满足以下条件,处置器方法就会绑定(bind)到生产者方法或生产者字段:

  • 生产者方法或生产者字段由与处理程序方法相同的 bean 类声明,并且
  • 根据类型安全解析中定义的类型安全解析规则(使用原始类型和参数化类型的可分配性),生产者方法或生产者字段可分配给已处置的参数。

在您的具体情况下,您有生产者方法productB,它创建一个类型为{B, A, Object}的bean。这些类型派生自返回类型,并将包含类型本身、所有父类(super class)和所有实现的接口(interface) ( as stated here in CDI spec )。

然后您就有了两种处置器方法,一种使用处置器参数 A,另一种使用 B。如果有帮助的话,您可以将这些参数视为注入(inject)点 - 您的 ProduceB 生产者方法创建一个适合这两个处理程序的 bean,从而产生歧义,因为 Weld 最多需要为每个 bean 提供一个处理程序方法。 p>

如果您想详细了解类型安全解析的工作原理,请查看 here .

至于如何“解决”这种情况,我可以从我的头脑中想到两种方法(可能还有更多方法可以做到这一点):

  • 您可以在另一个 bean 中声明每个生产者+处置者。根据规范,处理程序需要在生产者所在的同一个 bean 中声明,这样就可以消除这个问题。
  • 您可以使用@Typed on the producer并将productB的类型限制为仅B.class,这也应该可以解决这种情况,但bean将不再有资格注入(inject)任何类型为的注入(inject)点>A.

关于java - 如何处理继承类型的多种处理方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58620550/

相关文章:

java - 将数组压缩为数字

java - 更新 JTable

java - 从 session 范围检索 @Named 托管 bean

java - JEE6 如何在观察者和被观察者之间建立联系(观察者模式)

jpa - 如何将我的 DAO Bean 从 EJB 更改为纯 CDI?

java - 动态获取 Apache Tomcat 服务器路径和端口

java - 从 Java 中的 Google DistanceMatrix 响应计算 2d 距离矩阵

java - CDI 动态 Bean 实例

java - org.jboss.classfilewriter.DuplicateMemberException 异常

java - @Singleton 对象上的 CDI @New。它能做什么?