选择某个CDI事件观察者

时间:2015-04-05 01:24:53

标签: java java-ee dependency-injection cdi java-ee-6

我有一些类可以观察到一些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
    }
}

1 个答案:

答案 0 :(得分:3)

这里的技巧是对事件和观察者进行资格认定。

See the jee6 tutorial here特别是使用@Credit@Debit限定符。

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

使观察员合格,然后致电。

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

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

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

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

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

编辑: 我只是想到了我对这个关于使用事件的哲学的看法。

  1. 触发事件的组件可以指定有效负载的特定类型和附加到事件的限定符,但不能并且实际上不应该选择将处理事件的观察者。
  2. 您可以为任何一个事件添加许多观察者。可能有:一个发送电子邮件;一个写一个审计日志;一个发短信;一个写JMS消息;还有更多因为单event.fire(...)电话而一次全部开火。
  3. 观察员应该像上述那样有一个目的。

  4. 观察员不应该依赖任何执行顺序(交易与非交易除外......见下文),因为无法保证。如果您需要保证订单,那么观察者应该发起一个不同的事件,该事件的观察者可以按顺序进行后续处理。

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