2015-04-05 3 views
0

У меня есть несколько классов, которые наблюдают за некоторым событием CDI. Можно ли объявить, какой класс следует использовать в разных случаях?Выберите определенного наблюдателя событий CDI

Например, у меня есть класс, который производят события:

class Producer 
    { 
     @Inject 
     private Event<SomeEvent> event; 
     public void fire() 
     { 
      event.fire(new SomeEvent()); 
     } 
    } 

И у меня есть два потребительских класса:

class ConsumerA 
{ 
     public void onEvent(@Observes SomeEvent event); 
} 
class ConsumerB 
{ 
     public void onEvent(@Observes SomeEvent event); 
} 

Как я могу использовать ConsumerA экземпляры в одном случае и ConsumerB экземпляры в другом случае?

мне нужно что-то вроде этого:

class UseCaseA 
{ 
    @Inject 
    Producer producer; 
    @Inject 
    ConsumerA consumerA; 
    public void doWork() 
    { 
     producer.fire(); //consumerA.onEvent() will be called 
    } 
} 
class UseCaseB 
{ 
    @Inject 
    Producer producer; 
    @Inject 
    ConsumerB consumerB; 
    public void doWork() 
    { 
     producer.fire(); //consumerB.onEvent() will be called 
    } 
} 
+0

Я хотел бы избежать, используя имя Producer для этого, если это не имеет бизнес-значение, которое неизбежно. Методы и поля производителя в CDI являются дополнением к логике создания бонусов контейнера. – redge

ответ

3

Хитрость здесь заключается в Квалифицируйтесь как событие, и наблюдатель.

See the jee6 tutorial here В частности, использование @Credit и @Debit отборочных.

Чтобы сделать это динамически, вместо того, чтобы вводить различные события в огонь, вы можете использовать методы select(java.lang.annotation.Annotation... qualifiers) для одного события.

Оцените своих наблюдателей, а затем позвоните.

event.select(.... Some annotation literal. .).fire();

Вы можете иметь код пожара в суперкласса и затем каждый подкласс поставить пометку буквального.

Аннотация литерал - это javax.enterprise.util.AnnotationLiteral. вам нужно будет создать литерал аннотации для каждого квалификатора, который вы хотите использовать, но они могут быть созданы и переданы как объекты.

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

Вы также можете выбрать событие на основе подкласса класса событий, если это работает лучше.

EDIT: Просто подумал, что я добавлю свои мысли к этому вопросу о философии использования событий.

  1. Компонент, который стреляет событие может указать как конкретный тип полезной нагрузки и классификаторов, которые прикреплены к событию, но не и не должны фактически выбрать наблюдателя, который будет обрабатывать событие.
  2. Вы можете добавить много наблюдателей для любого события. Может быть: один отправить электронное письмо; Один для записи журнала аудита; Один для отправки текстового сообщения; Один, чтобы написать сообщение JMS; и много больше всех стрельбы сразу в результате одного звонка event.fire(...).
  3. Наблюдатели должны иметь ИМО одну цель, как описано выше.

  4. Наблюдатели не должны полагаться на какой-либо порядок исполнения (за исключением транзакционных и не транзакционных ... см. Ниже), поскольку он не может быть гарантирован.Если вам нужно гарантировать заказ, наблюдатель должен запустить другое событие, и наблюдатель для этого события может выполнить последующую обработку в заказе.

  5. Малые наблюдатели с одной единственной целью, как те, которые описаны выше, легко суперкласс, как часто большая часть кода идентична, например. для всех сообщений электронной почты, кроме формата сообщения.
  6. Если у вас есть 2 обновления для выполнения и не можете использовать XA для гарантии единственной атомной транзакции. Вы можете выбрать наиболее важный и сделать наблюдателя для того, который выполняется синхронно (в рамках транзакции об обстреле) и другого наблюдателя для другого, который выполняется после успешной транзакции об обстреле (используя during=AFTER_SUCCESS) таким образом, вы можете гарантировать, что либо : А и В будут; или A произойдет, но B не будет. Таким образом, вы даже можете ввести некоторую периодическую проверку распространения B по результатам A
  7. Параметр during аннотации @Observes может использоваться для обеспечения разделения между обработкой ядра, связанной с компонентом, запускающим событие и выполняемым синхронно (не транзакционные) и обработка, которая не должна выполняться, за исключением определенных обстоятельств, связанных с транзакцией, в которой происходит событие, и которая «поставлена ​​в очередь» для исполнения в этих обстоятельствах (транзакционная), например, регистрирует ошибку, если транзакция завершается с ошибкой; или отправить электронное письмо, если транзакция завершается успешно.
+0

Так что я не могу выбрать наблюдателей ** за пределами ** Логика производителя? Мне приснилось что-то вроде 'connect()' в qt Signals-Slots. – jekamax

+0

Что приводит производителя. Этот класс может предоставить Annotation.Literal. скажем, 'производитель.fire (новый BAnnotationLiteral());' – redge

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

  • Нет связанных вопросов^_^