JavaEE CDI中的Weld:Generic Events? [英] JavaEE CDI in Weld: Generic Events?

查看:116
本文介绍了JavaEE CDI中的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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆