Saturday, August 03, 2013

JSF/CDI Tip of the Day: @PostConstruct Lifecycle Interceptor

I was trying to come up with a way to inject a logger into a JSF managed bean that can be done prior to @Postconstruct. I was unsuccessful with this technique, but it was not a total loss. The examples I found on interceptors for life-cycle interception were "empty". They generally mention you can do it, but they did not show any real useful examples.

I hope to change that with this example. The example I demonstrate could be easily done with constructor injection, but in the case of a no-args constructor this may be your only opportunity to inject objects during @PostConstruct. I am going to suggest that if you want to make this functionality more general, you should use an interface and call the interface methods.

The InvocationContext will return Class<? extends T> using context.getTarget(). We can use this concept to control our injection to the object. In my case, I use setter injection on the object. Pretty cool!

The code for this example can be downloaded from here: cdi-lifecycle-interceptor-example

There are a couple of classes needed to set up our @Interceptor. The first is an interface we will call Loggable and the second is an @InterceptorBinding.

This is a simple interface which we will apply to the interceptor, and to the target class that we want to intercept.

The next class we need is our @Interceptor. This code contains all of the magic we need for the target class which we are intercepting.

As you can see we are making changes to the class after it is constructed, and before the @PostConstruct method is executed, i.e., context.proceed().

Finally, we need to have our class that we are intercepting. In this case, it is a simple @Named and @RequestScoped CDI bean.

The magic is complete, but I would recommend downloading the Maven based project to see the whole example here: cdi-lifecycle-interceptor-example

Our final output is shown here.

UUID Please?