使用@Priority 的 CDI 2 事件排序不起作用

CDI 2 Event ordering with @Priority not work

这个问题的答案描述了可以使用@Priority 注释对 CDI 事件进行排序。

Since CDI 2.0 (check here, Chapter 10.5.2), you may define an order using the @Priority annotation and specifying a number as its value. Observers with smaller priority values are called first and observers with no @Priority annotation gets de default priority (Priority.APPLICATION + 500). As with CDI 1.2, observers with same priority does not have any previously defined order and may be called by CDI container in any order.

CDI 2.0 observer ordering does not apply to asynchronous observer methods (per spec), as it's expected that observer methods get called as soon as it is possible and in different contexts. If you need some kind of ordering in you use case, you should make your asynchronous observer trigger the next event, instead of calling it from your "main" method.

So even if i fire Two different Event-Objects the order is not specified? – Noixes Jul 22 '20 at 6:45

Yes. Unless you are using CDI 2 and defining different priorities, the order is unspecified. You must realize that you may "discover" the order of a given implementation in such cases, but it is not recommended to rely on it because a future version of the same implementation may change it without colliding with the spec. –

但在我的示例中不起作用:

@Stateless
public class EventTest {

  @Inject
  @QualifierA
  private Event<String> eventA;

  @Inject
  @QualifierB
  private Event<String> eventB;


  @Test
  public void test() throws VerarbeitungsException {
    eventB.fire("B");
    eventA.fire("A");
  }

  public void observerA(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 1) @QualifierA String xml) {
    send(xml);
  }

  public void observerB(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 2) @QualifierB String xml) {
    send(xml);
  }

  private void send(String xml){
    System.out.println(xml);
  }
}

在我的测试类中,我触发了事件 B,然后触发了事件 A。测试日志显示 B/A,但我会按照 @Priority 的定义精确 A/B。我将 WildFly14 与 CDI 2.0 一起使用。事件排序是否仅适用于相同 event/qualifier 的观察者?

Event qualifiers

The event qualifiers act as topic selectors, allowing the consumer to narrow the set of events it observes. An event qualifier may be an instance of any qualifier type. Observer methods

An observer method allows the application to receive and respond synchronously to event notifications. And an async observer method allows the application to receive and respond asynchronously to event notifications. they both act as event consumers, observing events of a specific type, with a specific set of qualifiers. Any Java type may be observed by an observer method.

An observer method is a method of a bean class or extension with a parameter annotated @Observes or @ObservesAsync.

An observer method will be notified of an event if:

the event object is assignable to the type observed by the observer method,
the observer method has all the event qualifiers of the event, and
either the event is not a container lifecycle event, or the observer method belongs to an extension.

Blockquote

在您的代码中,您特别要求它观察具有不同限定符的事件。订单不会被强制执行。

改成试试:

  public void observesFirst(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 1) String xml) {
    send(xml);
  }

  public void observesSecond(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 2) String xml) {
    send(xml);
  }

顺序是在同一事件的观察者之间。但是您定义了两个具有不同限定符的事件。

要正确测试优先级,您应该只触发一个事件,并为该事件设置两个观察者。

例如:

@Stateless
public class EventTest {

  @Inject
  @QualifierA
  private Event<String> eventA;


  @Test
  public void test() throws VerarbeitungsException {
    eventA.fire("A");
  }

  public void observerA(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 1) @QualifierA String xml) {
    send("A: " + xml);
  }

  public void observerB(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Priority(value = 2) @QualifierB String xml) {
    send("B: " + xml);
  }

  private void send(String xml){
    System.out.println(xml);
  }
}