users@jersey.java.net

Re: [Jersey] IoCComponentProviderFactory and injection of Jersey-based artifacts ?

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Thu, 23 Jul 2009 16:25:24 +0200

On Jul 23, 2009, at 4:03 PM, Morten wrote:

> --- Den tors 23/7/09 skrev Paul Sandoz <Paul.Sandoz_at_Sun.COM>:
>>> Yes, I just tried that alternative also (Strange
>> though with the getInstance method that
>> IoCProxiedComponentProvider requires but is not used?).
>>
>> Yes, getInstance is not used, because Jersey instantiates.
>> One can think sort of think of it as a little glitch in the
>> design because everything inherits from
>> IoCComponentProvider.
>
> Ok, seems like the design need to be refactored and a new interface
> inserted in the middle which has this method and which anything but
> IoCProxiedComponentProvider inherits from.

Yes, but i do not want to break backwards compatibility. Things are
restricted by the return type of
IoCComponentProviderFactory#getComponentProvider


> In the mean time I suggest a comment is added to the javadoc about
> this ?
>

Done.


>> Note that Jersey has an explicit feature called @Inject
>> that explicitly defers to the set of registered
>> IoCComponentProviderFactory. So as a work around you can
>> annotate all your dependencies external to Jersey with
>> @Inject. The restriction with this solution is it only works
>> with classes and not types (like List<T>).
>
> Just tried that. Great workaround so far. Thanks!! Seems to work
> fine allthough I need to test a bit more. I did notice jersey's
> inject annotation before but I was not able to fully understand what
> I could do with it from the existing javadoc.
>
> It is a bit confusing to read our new code though, as we now have
> two similar Inject annotations that must be used as different
> places. "com.sun.jersey.spi.inject.Inject" in jersey controllers and
> javax.inject.Inject anywhere else (javax.inject.Inject is from the
> proposed JSR-330 Dependency Injection for Java from "http://code.google.com/p/atinject/
> " which Spring and Guice is going to use in addition to our own mini
> IVC utility).
>

I know it sucks :-(


> It would be cool if Jersey could be configured to recognize another
> alias for "com.sun.jersey.spi.inject.Inject". F.x. jersey could add
> a setInjectAlias(Class annotation) call on ResourceConfig or
> ContainerFactory) ? Suggestions ? Would that be possible to support
> in jersey ?
>

I think it is probably better to fix things as described below so one
does not have to use Jersey's @Inject.


>> For the solution where Jersey manages the life-cycle i
>> think we need a solution for Jersey to ask the
>> IoCComponentProviderFactory if it can resolve types. Thus an
>> implementation of IoCComponentProviderFactory could also
>> implement InjectableResolver:
>>
>> // Resolve scope + type + annotations to an
>> instance
>> public InjectableResolver {
>> Injectable<?> getInjectable(Scope s,
>> ComponentContext cc, Type t);
>> }
>
>>
>> When Jersey injects for constructor, field and methods, if
>> it cannot resolve an injection point from its own registered
>> injection stuff it can defer to the InjectableResolver
>> implemented by the IoCComponentProviderFactory
>> implementation. This has the advantage that as well as
>> constructors, resource methods, sub-resource methods and
>> sub-resource locators can also have stuff injected as
>> supplied by the IoCComponentProviderFactory.
>>
>>
>> For the solution where the IoC framework manages life-cycle
>> i think we need the IoCComponentProviderFactory
>> implementation to get an instance of InjectableResolver from
>> Jersey. Thus for constructor the factory can use the
>> InjectableResolver.
>>
>>
>> Make sense?
>
> Yes, that should work. At as I understand @PostConstruct would also
> work correctly as a consequence.
>

Yes.

Could you log an issue?

Thanks,
Paul.