JavaEE CDI中的Weld:Generic Events? [英] JavaEE CDI in Weld: Generic Events?
问题描述
我对基于泛型的特定事件处理有一个想法,但似乎Weld无法处理它们。我问谷歌,但找不到替代CDI扩展。
问题:是否有CDI扩展名,可处理泛型类型事件的事件传播?
我有三个一般事件,EntityCreated,EntityChanged和EntityDeleted 。它们的基类是这样定义的:
public abstract class DatabaseEvent< TargetType> {
public TargetType target;
public DatabaseEvent(TargetType target){
this.target = target;
$ / code>
事件是简单的继承类:
public class EntityCreatedEvent< TargetType>扩展DatabaseEvent< TargetType> {
public EntityCreatedEvent(TargetType target){
super(target);
我像这样解雇他们:
public abstract class MyHome< EntityType> {
私有EntityType实体;
@Inject
事件< 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){...}
}
这个解决方案是可以的,但并不完美。
解决方案我想你可以用dinamically绑定限定符成员来做到这一点。这就是你的代码的样子:
public abstract class MyHome {
private EntityType entity;
@Inject
事件< EntityCreatedEvent> entityCreatedEvent;
public void fireCreatedEvent(){
entityCreatedEvent.select(getTypeBinding())。fire(new EntityCreatedEvent(entity));
}
private TypeBinding getTypeBinding(){
返回新的TypeBinding(){
public Class< ;?扩展EntityType> value(){return entity.getClass();}
};
@Qualifier
@Target({PARAMETER,FIELD})
@Retention(RUNTIME)
public @interface EntityTypeQualifier {
类< ;?扩展EntityType>值();
}
公共抽象类TypeBinding扩展AnnotationLiteral< EntityTypeQualifier> implements EntityTypeQualifier {}
// Observers
public void handleEntityType1Created(@Observes @EntityTypeQualifier(EntityType1.class)EntityCreatedEvent event){}
public void handleEntityType2Created(@Observes @EntityTypeQualifier EntityType2.class)EntityCreatedEvent event){}
I have an idea for a specific event handling based on generics, but seems like Weld can't handle them. I asked google but couldn't find an alternative CDI extension for this.
Question: is there a CDI extension, that can handle event propagation of generic-typed events?
In the following the explicit problem I have.
I have three general events, EntityCreated, EntityChanged and EntityDeleted. The base class for them is defined like this:
public abstract class DatabaseEvent<TargetType> { public TargetType target; public DatabaseEvent(TargetType target) { this.target = target; } }
The events then are simple inherited classes:
public class EntityCreatedEvent<TargetType> extends DatabaseEvent<TargetType> { public EntityCreatedEvent(TargetType target) { super(target); } }
I fire them like this:
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); } }
I want to observe them like this:
public void handleProjectCreated(@Observes EntityCreatedEvent<Project> event) { ... }
When launching the server Weld tells me it can't handle generic-typed events. The CDI-way of doing things would be to use additional qualifiers instead of the generics to distiguish them, e.g.:
public void handleProjectCreated(@Observes @ProjectEvent EntityCreatedEvent event) { ... }
However, I fire the events from that
MyHome
base class, where I can't just fire with the@ProjectEvent
: it might not be a project but another type.My solution up to now is to skip that typing altogether and handle them like this:
public void handleProjectCreated(@Observes EntityCreatedEvent event) { if(event.target instanceof Project) { ... } }
This solution is okay, but not perfect.
解决方案I guess you can do this with dinamically binding qualifier members. This is what your code would look like:
public abstract class MyHome { private EntityType entity; @Inject Event<EntityCreatedEvent> entityCreatedEvent; public void fireCreatedEvent() { entityCreatedEvent.select(getTypeBinding()).fire(new EntityCreatedEvent(entity)); } private TypeBinding getTypeBinding() { return new TypeBinding() { public Class<? extends EntityType> value() {return entity.getClass();} }; } @Qualifier @Target({ PARAMETER, FIELD }) @Retention(RUNTIME) public @interface EntityTypeQualifier { Class<? extends EntityType> value(); } public abstract class TypeBinding extends AnnotationLiteral<EntityTypeQualifier> implements EntityTypeQualifier {} //Observers public void handleEntityType1Created(@Observes @EntityTypeQualifier(EntityType1.class) EntityCreatedEvent event) {} public void handleEntityType2Created(@Observes @EntityTypeQualifier(EntityType2.class) EntityCreatedEvent event) {}
这篇关于JavaEE CDI中的Weld:Generic Events?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!