2013-10-02 7 views
2

У меня есть идея для конкретной обработки событий на основе дженериков, но похоже, что Weld не справляется с ними. Я спросил Google, но не смог найти альтернативное расширение CDI для этого.JavaEE CDI в Weld: общие события?

Вопрос: существует ли расширение 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 говорит мне, что он не может обрабатывать события с типичным типом. ИПР-способ делать вещи было бы использовать дополнительные определители вместо дженериков для distiguish их, например:

public void handleProjectCreated(@Observes @ProjectEvent EntityCreatedEvent event) { ... } 

Однако, я огонь события из этого MyHome базового класса, где я не могу просто уволить с @ProjectEvent: это может быть не проект, а другой тип.

Мое решение до сих пор, чтобы пропустить набрав в целом и обращаться с ними так:

public void handleProjectCreated(@Observes EntityCreatedEvent event) { 
    if(event.target instanceof Project) { ... } 
} 

Это решение хорошо, но не идеально.

+1

Как утверждает Фабрицио, вам нужно будет использовать квалификаторы. Причина - из-за стирания типа. Во время выполнения все эти хорошо продуманные общие типы не существуют для системы типов, которые будут использоваться во время отражения (если только вы не пройдете действительно большие длины и не используете методы с использованием этих типов и т. Д.) И проверку типов во время событий. Вам лучше использовать квалификаторы. – LightGuard

ответ

6

Думаю, вы можете сделать это с помощью динамически связывающих членов классификатора. Это то, что ваш код будет выглядеть следующим образом:

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) {} 
Смежные вопросы