There Can Only Be One

An Introduction to CDI - Part 2

   

Interceptors


With Java EE 6, we can harness the power of AOP without AOP. Like in the previous example, using interceptors is very straightforward. There are 3 steps. Let’s implement a simple timer, for benchmarking purposes. The first step is the declaration of the interceptor. To do so, just use the @InterceptorBinding:

The second step is the interceptor implementation. It uses the @Interceptor annotation, coupled with the previously defined one:

Notice:

• the method annotated with @AroundInvoke returns an Object

• it uses a parameter of type InvocationContext

The last step is to declare such interceptors in WEB-INF/beans.xml because interceptors are deactivated by default.

The beans.xml also tells the container about how to order the interceptors in case there is more than one. There are two other interceptor types, @PostConstruct and @AroundTimeout (for EJB).

 

Decorators


Decorators – guess what – implement the Decorator design pattern. They are very similar to interceptors with two interesting differences:

 

• a decorator must implement the interface it is decorating (and yet can be abstract, so it does not have to implement the methods)

• a decorator can have a reference to the object it decorates.

 

It is done through injection Like interceptors, they must be referenced in the beans.xml file in order to be activated. Let’s take a simple example and create an interface which contract is to return an HTML representation of an object:

 

Now we need a date class that knows its HTML representation. I know the design is quite bad but bear with me, it’s just an example. Should one want a decorator that puts HTML inside <strong> tags, here’s the way:

Observers


CDI also implements the Observer design pattern, thus at last enabling simple event-driven development paradigm on the Java EE platform. The basis for it is the event type. An event type is a simple POJO. The Observer is also a POJO: in order for a method of the Observer to be called when an event is fired, just add a parameter of the right event type and annotate it with @Observes:

On the other side, the event producer should have an attribute of type javax.enterprise.Event parameterized with the same event type. In order to fire the event, call event.fireEvent() with an event instance:

Now, when sending a POST request to the servlet, the after- PostEvent() method of the EventObserverService will be called.

 

Alternatives


Previously, mock service was addressed by calling the setter and passing a newly created instance “by hand”. This is all fine and well in a unit testing case, but we also want to manage integration testing. The situation is thus the following:

 

• there are two implementations of the same interface on the classpath

• one cannot change the servlet code (for example, add a qualier to the service attribute)

 

Given the deterministic nature of CDI, we should basically be toast. In fact, nothing could be further from the truth. Just use the @Alternative annotation and CDI will conveniently ignore the annotated class.

 

What’s the point then to create it in the first place? Remember the unused-till-then beans.xml from above. It will come to our aid, since it accepts <alternative> tags. These tags activate the alternatives.

As such, one could have two beans.xml:

• a basically empty standard context

• and another integration testing context full of alternatives

Platform

This article was written with GlassFish v3, which uses Weld v1.0.1, as a platform. Weld is CDI reference implementation, and also a part of the Seam framework.

Conclusion

This article only brushes the surface of CDI. Nevertheless, it's an attempt at standardization and looks very promising. To go further:

Commons annotations (JSR-250) page: Commons annotations has annotation for DI in Java (@Resource)

CDI (JSR-299) page: amazingly enough, CDI is about DI in Java EE

Weld's documentation: Weld is CDI JBoss implementation and also the reference implementation

• Article on the merits of JSR-299 compared to the merits of JSR-330

Pages

Nicolas Frankel
Nicolas Frankel

What do you think?

JAX Magazine - 2014 - 06 Exclucively for iPad users JAX Magazine on Android

Comments

Latest opinions