(作为背景,我读过你认为你对 CDI 事件了如指掌……再想一想!所以我至少对 CDI 事件中的许多边缘情况非常熟悉。)
我使用 Weld 3.0.4.Final 作为 CDI 2.0 的实现。
我有一个AbstractFoo<? extends T>
我想作为 CDI 事件触发的实例。我们将其称为有效载荷。这就是我对有效载荷的全部了解。
T
定义为T extends MetaData
。 MetaData
是一个接口。
由于各种不重要的原因,我必须以编程方式触发有效负载,所以我这样做:
final Event<Object> cdiEventMachinery = beanManager.getEvent();
assert cdiEventMachinery != null;
final TypeLiteral<AbstractFoo<? extends T>> eventTypeLiteral = new TypeLiteral<AbstractFoo<? extends T>>() {
private static final long serialVersionUID = 1L;
};
final Event<AbstractFoo<? extends T>> broadcaster =
cdiEventMachinery.select(eventTypeLiteral, someQualifiers);
assert broadcaster != null;
显然,这里broadcaster
现在设置为触发我的有效载荷。我的意图是这些事件应该被传递给寻找AbstractFoo
由任何扩展类型参数化的 -or-its-subclasses 实例的观察者MetaData
。
但是当我这样做时broadcaster.fire(payload)
,我注意到像这样的观察者方法:
private final void onFoo(@ObservesAsync @MatchingQualifier final Foo<? extends MetaDataSubclass> event) {}
……不要被叫。 (这? extends MetaDataSubclass
似乎是罪魁祸首;如果观察到的参数很简单,Object
那么显然该方法会被通知。)
具体来说,假设:
- 一个
MatchingQualifier
字面量出现在someQualifiers
, 和 MetaDataSubclass
是一个扩展的类MetaData
,并且Foo
是一个扩展的类AbstractFoo
…为什么不调用观察者方法?
需要明确的是,我确信这不是错误,而是我的理解中缺少的东西。我想知道我错过了什么。
(交叉发布到developer.jboss.org。)
测试用例
这是一个使用更简单结构的测试用例。
private final void collectionExtendsNumber(@Observes final Collection<? extends Number> payload) {
System.out.println("*** collection extends Number");
}
private final void collectionExtendsInteger(@Observes final Collection<? extends Integer> payload) {
System.out.println("*** collection extends Integer");
}
private final void collectionInteger(@Observes final Collection<Integer> payload) {
System.out.println("*** collection Integer");
}
private final void collectionNumber(@Observes final Collection<Number> payload) {
System.out.println("*** collection Number");
}
@Test
public void testContainerStartup() {
final SeContainerInitializer initializer = SeContainerInitializer.newInstance();
initializer.disableDiscovery();
initializer.addBeanClasses(this.getClass());
try (final SeContainer container = initializer.initialize()) {
assertNotNull(container);
final BeanManager beanManager = container.getBeanManager();
assertNotNull(beanManager);
final TypeLiteral<Collection<? extends Number>> literal = new TypeLiteral<Collection<? extends Number>>() {
private static final long serialVersionUID = 1L;
};
final Event<Collection<? extends Number>> broadcaster = beanManager.getEvent().select(literal);
assertNotNull(broadcaster);
final Collection<? extends Number> payload = Collections.singleton(Integer.valueOf(1));
broadcaster.fire(payload);
}
}
只有第一个观察者方法被调用。我想了解是什么阻止了第二个被调用。我知道 an-unknown-type-that-is-a-Number
不能分配给 an-unknown-type-that-is-a- Integer
,但我想要一些方法来为有效负载选择“正确”的观察者方法.