2012-01-28 5 views
8

Можно ли использовать дисперсию типа в событиях CDI? вот так:Как использовать наследование и списки событий CDI?

  • Пусть у меня есть тип корневого события MyEvent и подкласс DummyEvent
  • Моя цель состоит в том, чтобы обработать список событий, полученным от удаленного источника List<? extends MyEvent>, содержащего DummyEvent экземпляров

Как я могу это сделать?

Если я выполняю цикл, вызывающий fire() на каждое событие, он будет вызывать @Observes MyEvent evt, но не @Observes DummyEvent evt методов.

** Обновление **

Создано образец кода, чтобы прояснить этот вопрос:

https://github.com/jfaerman/jfaerman/blob/master/test-cdi/src/main/java/jfaerman/App.java

Я хотел бы событие выстрелить дважды, один раз по отдельности и один раз из списка ,

+0

Какая реализация CDI вы используете? –

+0

сварка в jboss as 7 –

ответ

1

Mhh Я не понимаю ... как выглядит ваш фактический код для начала мероприятия? ASFAIK вы вставляете интерфейс javax.enterprise.event.Event и передаете экземпляр методу пожара, который тем самым объявляет вызываемого наблюдателя. И если наследование задействовано, как и в вашем случае, оба Observer будут вызваны, если вы запускаете DummyEvent. Если вы хотите дополнительно указать события, которые будут использовать Qualifiers.

@Inject @Any Event<DummyEvent> dummyEvent; 
... 
dummyEvent.fire(list.get(i)); 

/* редактировать */

"Проблема" является следующая строка кода:

weld.event().select(MyEvent.class).fire(evt); 

Как только вы specifiy тип мероприятия (MyEvent.class), фактический тип экземпляра события (evt) больше не имеет значения. Одна из возможностей - расширить класс hirachy с помощью Qualifiers. Например:

@ChildEvent.Child 
public class ChildEvent extends BaseEvent{ 

    @Qualifier 
    @Retention(RetentionPolicy.RUNTIME) 
    @Target({ElementType.TYPE, ElementType.METHOD, ElementType.FIELD, ElementType.PARAMETER}) 
    public @interface Child{ 
    } 

    public void eventAction() { 
     System.out.println("child"); 
    }  
} 

После этого дополнительно указать Observer:

public void observerChild(@Observes @ChildEvent.Child BaseEvent child){ 
     System.out.println("child with annotation event"); 
} 

Наконец, когда вы только доступ к базовым классам, как в вашем примере, где вы itarate через список, вы можете указать точный тип/спецификатор перед обжигом событие так:

for (BaseEvent e : list){ 
    childEvent.select(e.getClass().getAnnotations()[0]).fire(e); 
} 

Как уже упоминалось выше, если у вас есть общий наблюдатель (как показано ниже), он будет вызываться для каждого события.

public void observerBase(@Observes BaseEvent base){ 
    System.out.println("base event"); 
} 
+0

Пожалуйста, посмотрите пример кода, который я только что добавил, надеемся сделать проблему более понятной. –

+0

Отредактированный ответ, возможно, это помогает. –

+0

Это помогает, но там я использую только те типы ... спасибо за публикацию, узнал трюк :) –

Смежные вопросы