users@jersey.java.net

[Jersey] Re: Jersey's limit with Spring injection

From: Vetle Leinonen-Roeim <vetle_at_roeim.net>
Date: Wed, 16 Apr 2014 20:31:26 +0200

Hi,

The Spring injection has hopefully been changed for the better in Jersey
2.8 (master branch), which is still unreleased. If possible, try
downloading it from Github, building it, and testing with that.

Even so, your case seems very simple. I've used Spring and Jersey with
success myself, and have only had minor issues (which are all fixed with
the changes in Jersey 2.8). Perhaps you could provide a complete example
that we can take a look at?

To answer some of your questions; HK2 does the actual injection.
AutowiredInjectResolver is called with information from HK2 on what is
to be injected into, and it looks up the appropriate bean(s) in the
Spring context. In Jersey 2.8, the way it looks up the beans has been
changed, and should work better.

Regards,
Vetle


On 04/16/2014 07:21 PM, Michael-O wrote:
> Hi,
>
> I am examining Jersey's Spring module and is has a limitation as stated
> in the user guide:
>
> "Spring beans can't be injected directly into JAX-RS classes by using
> Spring XML configuration"
>
> I do not fully understand that and try to adapt that to my usecase. We
> have Spring 4.0.x, Jersey 2.7 in evaluation right now.
>
> I have modified the SpringComponentProvider because I was not satisfied
> with the way it interacts with Spring. The approach is now the same as
> in the Spring DispatcherServlet:
>
> 1. The Spring ContextListener creates a root context
> 2. The SpringComponentProvider retrieves this context and creates a
> child context on top of that
>
> The root context has some common beans like services, which require
> repositories and other stuff. The child context decares the resources
> beans-
>
> All dependencies are annotated with @Autowired, context component scan
> is not used but annotation config.
>
> Now my resource looks like this:
>
> // Located in the JAX-RS context, parent: root context
> @Component
> @Path(...)
> public Resource {
>
> @Autowired
> MyService service;
>
> @GET
> public String hello() {
> return service.hello();
> }
>
> }
>
> and the service:
>
> // Located in the root context
> public DefaultMyService implements MyService {
>
> @Autowired
> MyRepository repository;
>
> public String hello() {
> ...
> return repository.hello();
> }
>
> }
>
> As you can see, I have bean dependencies over two hierarchy levels.
>
> This approach works very well with the SpringWSServlet and JAX-WS Metro.
> When I deploy the same setup with Jersey, service remains null and is
> not wired. The AutowiredInjectResolver does not find the matching bean.
> The weird issue is that,
>
> 1. if I swap @Autowired for @Inject, everything is fine,
> 2. if I add "@Autowired Properties config" to Resource where the former
> is located in the root context, the wiring works perfectly.
>
> The questions are:
>
> 1. Is that the limitation mention in the user guide?
> 2. If not, who is cauesing that issue, the HK2 Spring Bridge, unable to
> handle context and/or bean hierarchies of the Jersey Spring module?
> 3. Why does @Inject work? More over, who is injecting, Spring or HK2?
>
> Help is very much appreciated,
>
> Michael
>