Jersey further improves CDI integration

Previous Jersey release 2.15 introduced new container agnostic CDI support. Nice feature that brings the capabilities of dependency injection also outside of the “big” containers. The well-known @Inject annotation can be used even in a lightweight http server, such as Grizzly. Jakub Podlešák, the author of this feature describes how to configure and use it in his very informative blogpost.

In the latest (and greatest) 2.16 release (Feb 2015), this feature was further improved and the integration with Jersey’s injection library, hk2, is tighter now in both directions.

Inject annotated bean into resource

Basic use case is to inject a non JAX-RS @RequestScoped CDI bean into your resource. The injected bean can have JAX-RS parameter annotations, such as @FormParam, @PathParam, etc.

Let’s create an annotated JAX-RS resource:

and a CDI bean containing JAX-RS annotations, e.g.:

If you send a request, that invokes the resource method, hk2 will inject the @QueryParam annotated parameters and CDI will inject the constructed bean into the field in your resource. Same principle applies to @FormParam, @PathParam, etc.

Like it? There’s more…

The bean you are injecting does not have to be request scoped. Say you have some “global” data stored in an @ApplicationScoped  CDI bean. It works the same way, just another @Inject into your resource:

and create the bean you want to inject:

CDI takes care of the injection, so in your resource method, you can do e.g.:

 

@Context injection into non JAX-RS elements

Things do work both ways, not only you can inject CDI beans into both JAX-RS and non JAX-RS components, but also CDI beans in any scope can have fields annotated with @Context and be injected with data provided by Jersey runtime.

For instance, adding:

into the application scoped bean from above will make the UriInfo (injected by JAX-RS into CDI bean) accessible in the resource via the application scoped bean (injected by CDI into JAX-RS bean).
Of course, this example is a bit artificial, it would be more practical to inject directly to the resource, but just for the sake of the demonstration, this shows such combinations are now possible.

3 ways

This might actually be just a small side-note, but all the snippets used the injection into a member field by annotating the variable declaration. There are, as you probably expect, two more ways. All are equivalent, just use the one you just need or the one you like the best and is the most readable for you.

When sticking with he original @BeanParam example, those three snippets are interchangeable.

setter injection

constructor injection

field injection

(as already shown above)

 Complete example

This blogpost contains only small snippets to demonstrate some of the new possibilities. If you want to see the new feature in action (although still “artificial”), you can browse the code of this complete example (well, ok… it is actually an integration test, but it can serve as an example). It shows wider range of usages and how both injection mechanisms can co-exist next to each other – in a single class if you want.

Hopefully you will find the new improvements (and the container-agnostic CDI support itself) useful and enjoyable!

 

 

 

One Response to “Jersey further improves CDI integration

Leave a Reply

Your email address will not be published. Required fields are marked *