users@jersey.java.net

Re: [Jersey] GuiceComponentProviderFactory.isInjectPresent only looks at constructors

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 15 May 2009 16:39:24 +0200

Hi,

There are some docs on the package of the servlet:

https://jersey.dev.java.net/nonav/apidocs/1.1.0-ea/contribs/jersey-guice/com/sun/jersey/guice/spi/container/servlet/package-summary.html

but i think we need some on the GuiceComponentProviderFactory as well.

I am guessing you are not explicitly binding your classes in a module,
correct?


I just made a change in the trunk so you can override the
functionality. I renamed the method "isInjectPresent" to
"isImplicitGuiceComponent" and you can override to modify what is
considered to be an implicit Guice component.

Paul.

On May 15, 2009, at 3:53 PM, Zach Cox wrote:

>>> Is there a specific reason that
>>> GuiceComponentProviderFactory.isInjectPresent only looks for Guice's
>>> @Inject annotation on constructors?
>>
>> I thought that was the easiest solution for the case when Guice
>> instantiates
>> but Jersey manages the life-cycle. To enable such support you have to
>> annotate a constructor with @Inject, and of course the class must
>> not be
>> explicitly bound. Do you think we should loosen such requirements
>> to detect
>> such cases?
>
> I originally had a case like this:
>
> public abstract class AbstractResource
> {
> private Something something;
>
> @Inject
> public void setSomething(Something something)
> {
> this.something = something;
> }
>
> protected void doThing()
> {
> //do some stuff using the something object...
> }
> }
>
> @Path("/blah")
> public class BlahResource extends AbstractResource
> {
> @GET
> public String get()
> {
> doThing();
> return "whatever";
> }
> }
>
> So an abstract base resource class with a doThing() method that can be
> reused by any resource class that extends the base. doThing() needs a
> Something object which Guice injects. The best way to get Guice to
> inject dependencies into an abstract base class seems to be to use
> method injection (otherwise you end up with every subclass getting
> deps injected into their constructors and calling the same super
> constructor).
>
> Originally the Something was not being injected since BlahResource
> defines no constructor injection. I've actually refactored into
> something more like this now:
>
> public interface Thing
> {
> public void doThing();
> }
>
> @Path("/blah")
> public class BlahResource
> {
> private Thing thing;
>
> @Inject
> public BlahResource(Thing thing)
> {
> this.thing = thing;
> }
>
> @GET
> public String get()
> {
> thing.doThing();
> return "whatever";
> }
> }
>
> So I still get reusable doThing() behavior by injecting Thing
> instances into resource class constructors (plus I can mock them out
> in unit tests too). I think this is a better design than the abstract
> base resource class approach, but it still might be useful to at least
> support method injection on resource classes, if not field injection
> as well. Constructor, Method, and Field all extend AccessibleObject
> which defines the isAnnotationPresent method that isInjectPresent
> uses, so it should be able to easily support method & field injection
> too.
>
> Better yet, maybe isInjectPresent should be protected so we can
> override & customize its behavior as necessary? At the minimum,
> GuiceComponentProviderFactory needs some javadocs that specify "Guice
> will only inject dependencies into your resource class if it defines
> constructor injection".
>
> Thanks,
> Zach
>
>
>> For explicitly bound classes the
>> GuiceComponentProviderFactory.isInjectPresent is never utilized and
>> there
>> are no restrictions imposed by Jersey on what should be annotated.
>>
>> Paul.
>>
>>
>>> Guice also supports method and
>>> field injection. By not looking for @Inject on methods and fields,
>>> resource classes that use method or field injection but not
>>> constructor injection are not handled by Guice at all.
>>>
>>> Thanks,
>>> Zach
>>>
>>> ---------------------------------------------------------------------
>>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>>
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
>> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>>
>>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>