提供以下课程
private static class ProducedInSubClass {
}
private static class ProducedInSuperClass {
}
public static class SuperClass {
@Produces
public ProducedInSuperClass producedInSuperClass = new ProducedInSuperClass();
}
public static class SubClass extends SuperClass {
@Produces
ProducedInSubClass producedInSubClass = new ProducedInSubClass();
}
public static class BeanWithSubClass {
@Inject
SubClass subClass;
@Inject
ProducedInSuperClass producedInSuperClass;
@Inject
ProducedInSubClass producedInSubClass;
}
对ProducedInSuperClass的注入仍然不满意。我知道这与CDI规范第4.2章是一致的。
要执行此操作,我需要通过
扩展SubClass。 @Produces
ProducedInSuperClass producedInSuperClassInSubClass = producedInSuperClass;
有人可以对此进行解释吗?为什么“注入,注释拦截器...”是继承的,而不是“生产者”?
答案 0 :(得分:5)
有什么理由只对静态类进行操作?生产者需要放置在要识别的实际CDI bean上。您的样本已脱离上下文,因此我无法确定它们是否将被实际识别为bean。
但是,将您的样本转移到非静态测试用例(有一些@Vetoed豆并为其生产者),它将按照您的预期运行-将找到两个生产者并生产可注射的豆。因此,也许您需要共享完整的可重现样品,我们可以从那里开始。
我怀疑您要问的继承不是这里的实际问题。
无论如何,从CDI 1.0开始就这样设计,因此最好就此进行讨论很麻烦(至少没有JIRA问题,我确实检查过那里)。
但是立即想到的一个原因-假定继承对于生产者来说已经存在。这样,您的上述情况在ProducedInSuperClass
中将有一个SuperClass
的生产者,但由于在SubClass
中也将继承。假设两者都是合法的注入对象(没有通过专门化禁用),那么您现在面临一个模棱两可的依赖异常,因为您有两个具有相同bean限定符的相同bean类型的生产者,因为SuperClass
和SubClass
是两个不同的豆并且都包含一个生产者。
我要说的是在生产者上禁用继承的合理原因。此外,仍然保持继承状态,然后可以重写子类中的方法,并出现更多问题-是否同时保留这两个方法?如果保留它们,新方法的局限性是什么?如果您决定选择其中一个,然后@Vetoed
一个豆,该怎么办?
在我看来,这只是设计决定。可能到位以防止进一步的混乱。虽然我知道这不是答案,所以您可能正在寻找,但质疑如此古老的设计很少会提供更准确的答案:-)
答案 1 :(得分:3)
为什么...是继承人,而不是生产者?
生产者方法和字段不被bean子类继承。
如果将继承生产者方法和字段,那么将存在多个可...注入到注入点的豆,CDI将其视为ambiguous dependency。
另一方面,CDI支持producer method specialization:
@Mock
public class MockShop extends Shop {
@Override @Specializes
@Produces
PaymentProcessor getPaymentProcessor() {
return new MockPaymentProcessor();
}
@Override @Specializes
@Produces
List<Product> getProducts() {
return PRODUCTS;
}
...
}