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 14:53:32 +0200

On Jul 23, 2009, at 1:57 PM, Morten wrote:

> --- Den tors 23/7/09 skrev Paul Sandoz <Paul.Sandoz_at_Sun.COM>:
>>> So far so good. Remaining problems are:
>>>
>>> 1) How to inject jersey artifacts into the constructor?... how do
>>> we >>get hold of an instance of the class
>>> IoCComponentProcessorFactory ?
>
>> IoCComponentProcessorFactory will only work for field/method
>> injection. >Plugable constructor injection is always problematic.
>
> Yes, whoever constructs the object should be able to do CTR
> injection if it has access to all the artifacts in question. I could
> provide a lookup/factory method (key java.lang.Class) to jersey if
> jersey constructs or if I constructs the object I could inject
> jersey CTR parameters if I get access to a lookup/factory method to
> jersey artifacts ? Both scenarious would be acceptable for me if it
> would work?
>
>>> 2) How to call @Postconstruct once Jersey has finished injecting
>>> its >>jersey artifacts?
>> Unfortunately it is currently not possible to support injection
>> b>efore >@PostConstruct.
>
> Yea, that is also my conclusion unfortunately.
>
>>> You can use is IoCProxiedComponentProvider and in the proxy method
>>> >>perform injection and then return the same instance. But the
>>> proxy >>method will be called after @PostConstruct. The use of an
>>> >>IoCProxiedComponentProvider means that Jersey will control the
>>> >life-cycle.
>
> 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.


> With that jersey constructs an injects all it's artifacts, but my
> own stuff is injected after Postconstruct as you mentioned + I won't
> inject my own artifacts in the CTR as jersey don't know how to deal
> with them.
>
>> Does your IvC framework control the life-cycle (scope, post
>> construct >and pre destroy) of the instantiated components ? or can
>> you defer to >Jersey to do that ?
>
> How control the life-cycle is not important (both would be
> acceptable) but it IS important that both jersey and non-jersey
> artifacts can be injected into fields, parameters and constructor
> and that PostConstruct gets called AFTER all injections.
>
>> The answer to that question can help determine what sort of fix
>> would >be required to support what you need.
>
> The answer is both would work for me (whatever is easiest).
>
>> For example, if the former then for each constructor parameter that
>> you >cannot bind there will need to be a way to ask Jersey if it
>> can. If the >latter then we need to interpose between instantiation
>> and post >construction and allow third party injection.
>
> Hmmm. Seems like Jersey would need an API change ?

Yes.


> Details ? What can be done do you think?
>

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>).


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?

Paul.