Mastering Java EE Development with WildFly
上QQ阅读APP看书,第一时间看更新

Observer methods

Other than injecting the event, we can declare methods that observe the event; and when the event is started, they intercept the event and do operations.

Here is a sample of an observer:

public class AlwaysObserver {
public void inProgress(@Observes Bill event) {
...
}
...
}

When the fire method of the Bill Event is executed, the CDI engine automatically searches all methods with parameters marked as @Observes and with class Bill and executes them. In this sample, the observer method is executed in any case. See now the different cases of observer methods.

See this observer method:

public void inProgress(@Observes(notifyObserver = IF_EXISTS) Bill event) {
...
}

The parameter value IF_EXISTS restricts the use of the observer method only if the observer class is created. To do this, you need the AlwaysObserver class injected in some context.

The during parameter works inside a transaction. It restricts the observer method depending on the transaction state. Here are the available transactional states:

  • BEFORE_COMPLETION: The observer method is started shortly before the completion phase of the transaction
  • AFTER_COMPLETION: The observer method is started shortly after the completion phase of the transaction
  • AFTER_FAILURE: The observer method is started after the failure phase of the transaction, after the rollback
  • AFTER_SUCCESS: When the transaction completes successfully, the observer method is started

To test execute annotated methods, simply start the event inside a transaction:

Try {
userTransaction.begin();
Bill bill = new Bill();
billEvent.fire(bill);
userTransaction.commit();
} catch (NotSupportedException | SystemException | SecurityException | IllegalStateException | RollbackException
| HeuristicMixedException | HeuristicRollbackException e) {
try {
userTransaction.rollback();
} catch (SystemException se) {}
}

If the commit succeeds, the following observer methods will be executed during the commit:

public void beforeCompletion(@Observes(during = BEFORE_COMPLETION) Bill event) {...}
public void afterSuccess(@Observes(during = AFTER_SUCCESS) Bill event) {
...}
public void afterCompletion(@Observes(during = AFTER_COMPLETION) Bill event) {...}

If the commit fails, the following observer methods will be executed during the rollback:

public void afterFailure(@Observes(during = AFTER_FAILURE) Bill event) {...}
public void afterCompletion(@Observes(during = AFTER_COMPLETION) Bill event) {...}

An important annotation introduced in the Java EE 7 is @Priority. If we have more interceptors or observer methods acting on the same resource or bean, we can annotate them forcing the priority, so we can decide who starts before whom. In our case, we can have two observer methods using the @Observes annotation annotated on the Bill event:

@Priority(PLATFORM_BEFORE + 1)
public class AlwaysObserver {
public void inProgress(@Observes Bill event) {
...
}
...}
@Priority(PLATFORM_BEFORE)
public class IfExistsObserver {
public void inProgress(@Observes(notifyObserver = IF_EXISTS) Bill event) {
...
}
...}

If IfExistsObserver is injected, they will start both. The priority signifies that the inProgress method of IfExistsObserver will start earlier because the priority number is lower.