News Ticker

CDI 2.0: 100DaysOfJavaEE8

100 Days Of Java EE 8: Solution

CDI Observer Challenge

The CDI 2.0 API introduces the @Priority annotation that allows the order of observer methods. When the fire() method is called, in what order are the observer methods executed?

CDI_2.0_observer_priority

Solution

The observe methods are executed in this order: 2, 1, 3, 5

The method observer4() does not get called because it uses the @ObservesAsync annotation and only fires when the fireAsync() method is called.

What are Observers and Priority?

In CDI 1.1, observers are invoked synchronously with no mechanism to determine the order in which they are called. The issue this causes is that if an observer throws an exception, all uncalled observer methods are not invoked and the observer chain ceases. In CDI 2.0, this has been mitigated to some extent by the introduction of the @Priority annotation. This annotation is added to the observer method parameter list and an order value is specified.  Smaller numbers are called first and the default order is javax.interceptor.Interceptor.Priority.APPLICATION + 500.

CDI Observers and Priority in Action

In the code snippet below the synchronous event of type AuditEvent is fired.

@Inject
private Event<AuditEvent> event;

@PostConstruct
public void send() {
    event.fire(new AuditEvent("Security Violation", HIGH));
}

The following observers exist in your application.

// 1
public void observe1(@Observes @Priority(1000) AuditEvent auditEvent) {}

// 2
public void observe2(@Observes @Priority(100) AuditEvent auditEvent) {}

// 3
public void observe3(@Observes @Priority(APPLICATION + 500) AuditEvent auditEvent) {}

// 4
public void observe4(@ObservesAsync @Priority(1) AuditEvent auditEvent) {}

// 5
public void observe5(@Observes @Priority(5000) AuditEvent auditEvent) {}

The order in which the observers are executed is determined by the @Priority annotation. The lower numbered priorities are executed first. The value of the observe3() method priority is 2500 (the value of APPLICATION is set as a constant in the javax.interceptor.Interceptor.Priority.APPLICATION; class as 2000).

Note that the observe4() method is annotated @ObservesAsync which only executes when the fireAsync() method is called. So in this code example, it will not be executed. Also, note that it does not make sense to add a @Priority annotation to an async method as these methods are executes asynchronously.

So the order in which the observe method is executed is: 2, 1, 3, 5.

Further Reading

For further information on how to use CDI 2.0’s new features please take a look at my article What’s new in Java EE 8 over at IBM developerWorks and also you should read the specifications for the Contexts and Dependency Injection for Java 2.0 (JSR 365).

GitHub Repository

The code from this and all other #100DaysOfJavaEE8 can be found in my GitHub repository.

The Original Tweet

Leave a Reply

%d bloggers like this: