Observable Event example with CDI 2.0 (Java EE 8)

Demo: http://javademo.io/cdi-weather Code source: GitHub

With Java EE 8 CDI will receive a major upgrade. Between the new major features we can find:

In this demo we will build a small example using these new features. You can find the code on GitHub.

Weather station : requirements

In this example we simulate a Weather station that has to notify multiple observer every time the weather changes.

There are 3 clients (Observers):

Technical implementation

The clients are Observers that need to be notified when an event occours. The TV Channel Observer:


@Stateless
public class TVChannelsChangeObserver {
    public void notifyTVChannel(@Observes WeatherEvent weatherEvent) {
       weatherEvent.addEvent("TV Channel informed about the " + weatherEvent.getCurrentWeather());
    }
    
    public void sendDetailedReport(@ObservesAsync WeatherEvent weatherEvent) {
        weatherEvent.addEvent("ASYNCH : TV Channel, detailed email report sent");
    }
}

The class has two methods: one annotated with @Observes receives the synchronous WeatherEvent (notifyTVChannel), one annotated with @ObservesAsynch receives the async WeatherEvent.

WeatherEvent is a simple POJO that can be used to fire an Event.

public class WeatherEvent {
    private String currentWeather;

    public WeatherEvent(String currentWeather) {
        this.currentWeather = currentWeather;
    }
}

The Emergency Services have to be alerted only in case of ‘emergency‘, in this case we can use a @Qualifier to filter the notification received:

public void sendAlarm(@Observes @WeatherType(value = "emergency") WeatherEvent weatherEvent) {
    weatherEvent.addEvent("EMERGENCY communication sent!!! They will come soon!");
}    

How to fire the events

To fire the event we need to inject the WeatherEvent 2 times in our service or controller class. One time for the sync Event, the second time for the async Event (with the @Qualifier WeatherType).

@Inject
Event<WeatherEvent> weatherEvent;

@Inject
@WeatherType(value = "emergency")
Event<WeatherEvent> emergencyEvent;

If we receive an emergency alert we fire the Event of type ’emergency’ (emergencyEvent), otherwise we fire a simple ‘weatherEvent’.

WeatherEvent weatherSubject = new WeatherEvent(weatherRequestBean.getWeather());

if (weatherRequestBean.getEmergency()) {
    emergencyEvent.fire(weatherSubject);
    emergencyEvent.fireAsync(weatherSubject);
} else {
    weatherEvent.fire(weatherSubject);
    weatherEvent.fireAsync(weatherSubject);
}

The container automatically call the Observers interested:

The advantage of this solution is that you can add new Observers (e.g. newspaper, Twitter etc.) without any change to the application logic.

How to test it

You can go on http://javademo.io/cdi-weather and play with it 🙂