选择某个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
    }
}

这里的技巧是限定事件和观察者。

请参阅此处的jee6教程,特别是@Credit@Debit限定符的使用。

要动态执行此操作,而不是注入不同的事件来激发,可以对单个事件使用select(java.lang.annotation.Annotation... qualifiers)方法。

确认您的观察员资格,然后致电。

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

您可以将fire代码放在一个超类中,然后让每个子类提供注释文字。

注释文字是javax.enterprise.util.AnnotationLiteral。您需要为要使用的每个限定符创建一个注释文字,但这些限定符可以实例化并作为对象传递。

顺便说一句,你不需要注入你的观察者。这违背了观点。您应该能够为每个事件添加任意数量的观察者,而不必重新访问事件的源。您的容器应该在启动时实例化它们。

如果效果更好,您也可以根据事件类的子类来选择事件。

编辑:我只是想把我的想法添加到这个关于使用事件的哲学中。

  1. 激发事件的组件可以指定负载的特定类型和附加到事件的限定符,但实际上不应该也不应该选择将处理事件的观察器
  2. 您可以为任何一个事件添加多个观察者。可能有:一个发送电子邮件;一个是编写审计日志;一个是发送短信;一个是编写JMS消息;并且作为单个CCD_ 7调用的结果,更多的全部同时发射
  3. 观察员应该有一个像上述那样的单一目的。

  4. 观察者不应依赖任何执行顺序(事务性与非事务性除外…见下文),因为这是无法保证的。如果您需要保证顺序,那么观测者应该激发一个不同的事件,该事件的观测者可以在顺序中进行后续处理。

  5. 像上面描述的那些具有单一目的的小型观察者很容易超类,因为通常大多数代码都是相同的,例如,对于除消息格式之外的所有电子邮件
  6. 如果您有两个更新要执行,并且不能使用XA来保证单个原子事务。您可以决定最重要的一个,并为同步执行的一个(在激发事务内)创建一个观察者,为另一个在激发事务成功后执行的观察者(使用during=AFTER_SUCCESS)创建另一个不同的观察者,这样您就可以保证:a和B会发生;或者A会发生,但B不会。这样,你甚至可以进行一些定期检查,从A的结果中传播B
  7. @Observes注释的during参数可用于提供与触发事件并同步执行(非事务性)的组件相关联的核心处理与处理之间的分离,这些处理必须在与触发事件的事务相关的某些情况下进行,并且在这些情况下"排队"执行(transactional)例如,如果交易失败,则记录错误;或者如果交易成功则发送电子邮件

最新更新