【发布时间】:2013-10-08 17:35:09
【问题描述】:
我有一个基于泛型的特定事件处理的想法,但似乎 Weld 无法处理它们。我问了谷歌,但找不到替代的 CDI 扩展。
问题:是否有 CDI 扩展,可以处理泛型事件的事件传播?
以下是我遇到的明确问题。
我有三个常规事件,EntityCreated、EntityChanged 和 EntityDeleted。它们的基类是这样定义的:
public abstract class DatabaseEvent<TargetType> {
public TargetType target;
public DatabaseEvent(TargetType target) {
this.target = target;
}
}
这些事件是简单的继承类:
public class EntityCreatedEvent<TargetType> extends DatabaseEvent<TargetType> {
public EntityCreatedEvent(TargetType target) {
super(target);
}
}
我这样解雇他们:
public abstract class MyHome<EntityType> {
private EntityType entity;
@Inject
Event<EntityCreatedEvent<EntityType>> entityCreatedEvent;
public void fireCreatedEvent() {
EntityCreatedEvent<EntityType> payload = new EntityCreatedEvent<EntityType>(entity);
entityCreatedEvent.fire(payload);
}
}
我想这样观察他们:
public void handleProjectCreated(@Observes EntityCreatedEvent<Project> event) { ... }
在启动服务器时,Weld 告诉我它无法处理泛型类型的事件。 CDI 的做事方式是使用额外的限定符而不是泛型来区分它们,例如:
public void handleProjectCreated(@Observes @ProjectEvent EntityCreatedEvent event) { ... }
但是,我从 MyHome 基类触发事件,我不能只使用 @ProjectEvent 触发:它可能不是一个项目,而是另一种类型。
到目前为止,我的解决方案是完全跳过该输入并像这样处理它们:
public void handleProjectCreated(@Observes EntityCreatedEvent event) {
if(event.target instanceof Project) { ... }
}
这个解决方案还可以,但并不完美。
【问题讨论】:
-
Fabricio 提到您需要使用限定符。原因是类型擦除。在运行时,所有这些精心设计的泛型类型都不适用于类型系统在反射期间使用(除非您经历了非常长的时间并且有使用这些类型的方法等)和事件期间的类型检查。最好使用限定符。
标签: events generics java-ee-6 cdi weld