【发布时间】:2023-04-08 03:49:01
【问题描述】:
(作为背景,我读过 You think you know everything about CDI events… Think again!,所以我至少对 CDI 事件中的许多边缘情况非常熟悉。)
我使用 Weld 3.0.4.Final 作为 CDI 2.0 的实现。
我有一个 AbstractFoo<? extends T> 实例,我想将它作为 CDI 事件触发。我们称之为payload。这就是我对有效载荷的全部了解。
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,但我想要一些方法来选择“正确" 有效载荷的观察者方法。
【问题讨论】: