users@jersey.java.net

[Jersey] Re: method injection with guice

From: Christopher Currie <christopher_at_currie.com>
Date: Tue, 19 Jul 2011 15:29:49 -0700

On Tue, Jul 19, 2011 at 3:09 PM, Christopher Piggott <cpiggott_at_gmail.com> wrote:
> Then, I thought let's try method injection, so I changed the class to this:
>
> @Path("/")
> @RequestScoped
> public class Test {
>        @GET
>        @Produces({MediaType.TEXT_PLAIN})
>        @Path("test")
>        @Inject public String get(@Named("greeting") String greeting) {
>                System.out.println("Returning a greeting " + greeting);
>                return greeting;
>        }
> }

> So it's trying ... but it called my resource method three times; twice
> properly injected, once not... and a zero-content-length response.
>
> I'm not sure quite what to make of this.  Should this work?

No. The behavior you're seeing is because injection is done by Guice,
and calling your resource is done by Jersey, and the only overlap
between the two is that Jersey asks Guice when it needs a new instance
of an object, in this case, your root resource. There is no way for
Guice to be involved in injecting the parameters of Jersey resource
methods, because Jersey is calling them, not Guice.

Method injection is designed for bean-type classes with no-arg
constructors and setter/getter pairs for bean properties. If you want
method injection, you need to keep your instance variable for greeting
and create an @Inject annotated "setGreeting" method to set it.
You're seeing odd behavior because Guice looks at the "get" method,
sees that it's annotated with @Inject, and calls it thinking it's
calling a setter method. This happens before the object is even sent
back to Jersey, which then calls it again because of the @GET and
@Path annotations.

I'm not sure where the third call is coming from, but it's being
called by Guice, so Jersey must have asked for another instance of
your resource, though I'm not sure why.

HTH,
Christopher