jsr339-experts@jax-rs-spec.java.net

[jsr339-experts] Re: [jax-rs-spec users] Re: Re: Re: Back To DI in Subresources

From: Marek Potociar <marek.potociar_at_oracle.com>
Date: Fri, 27 Apr 2012 13:27:21 +0200

On Apr 20, 2012, at 10:47 PM, Sergey Beryozkin wrote:

> On 20/04/12 19:34, Marek Potociar wrote:
>>
>> On Apr 19, 2012, at 11:01 AM, Sergey Beryozkin wrote:
>>
>>> On 17/04/12 16:37, Santiago Pericas-Geertsen wrote:
>>>>
>>>> On Apr 17, 2012, at 7:45 AM, Marek Potociar wrote:
>>>>
>>>>> There are 2 solutions that I've been thinking about:
>>>>>
>>>>> 1. introduce an injectable request-scoped ResourceContext with
>>>>> methods like inject(Class<?> subresourceClass), inject(Object
>>>>> subresource)
>>>>> 2. update the spec to mandate field injection on the sub-resource
>>>>> instances returned by sub-resource locator.
>>>>>
>>>>>
>>>>> So far I am leaning towards #1 as it seems more flexible.
>>>>>
>>>>> Any thoughts on the above?
>>>>
>>>> Why not both? As you say, (1) is more flexible but (2) is quite convenient.
>>>>
>>>
>>> I don't understand how the sub-resource injection can work at all.
>>> Lets take an example where a root resource is a singleton.
>>>
>>> This root resource can return sub-resource instances. Such instances can be created at a per-request basis or may've been pre-allocated and are singletons too. Only the root resource knows the rules.
>>
>> Again, that's why I am leaning towards #1 as it is more flexible and lets the parent resource decide whether or not the injection should be used and how.
>>>
>>> How can the runtime make sure that the injection into sub-resources is thread-safe ?
>>
>> It should not. It should be the responsibility of the parent resource.
>
> OK. I may've mis-read the original proposal, sorry if I am.
>
> What sort of DI is being discussed here ?
> I'm saying that something like
>
> public RootResource {
> private SubResource mySubResource;
> @Path
> public SubResource getSubResource() {
> return mySubResource;
> }
> }
>
> public SubResource {
> @Context
> private UriInfo ui;
> @GET @Produces("text/plain")
> public String getTest() {
> return "subresource";
> }
> }
>
> specifically the injection of UriInfo into SubResource is difficult for the runtime to support because it is not aware of SubResource's lifecycle.
> You are saying the injection is the responsibility of the parent resource (RootResource), so we can expect SubResource have a UriInfo setter for example. I agree, this is what the spec says now.
>
> So, what DI support is actually being discussed in this thread ?
> Can you please type some code ?

What I have in mind is something like:

@Path("root")
public class RootResource {
    @Context ResourceContext ctx;

    @Path("sub1")
    public SubResource getSubResource() {
        return ctx.inject(SubResource.class); // instantiate & inject
    }

    @Path("sub2")
    public SubResource getSubResource() {
        SubResource sr = ... obtain the custom-managed instance somehow ...
        return ctx.inject(sr); // inject the instance
    }
}

public class SubResource {
    @QueryParam("q") private String query;
    @Context private UriInfo uriInfo;
    
    ...
}

In "sub1" case the root resource should be able to ask JAX-RS runtime to provide a new injected sub-resource instance. In "sub2" case the resource should be able to retrieve the sub-resource instance in a custom way, but if it decides that it still wants to inject the instance, it should be able to do so. Makes sense?

Marek
>
> Cheers, Sergey
>>
>> Marek
>>
>>>
>>> Thanks, Sergey
>>>> -- Santiago
>>>>
>>>>>> Hi,
>>>>>>
>>>>>> I would like to re-activate the already mentioned issue of lack of
>>>>>> support of DI in sub-resources.
>>>>>>
>>>>>> Usually you are going to separate JAX-RS resources and services into
>>>>>> separate classes. In that case services are going to be injected into
>>>>>> resource with @Inject (it works already fine in Java EE 6).
>>>>>>
>>>>>> However: usually JAX-RS runtime is navigating from the main Resource
>>>>>> to the sub-resource class via the @Path annotation.
>>>>>>
>>>>>> As developer you are creating a sub-resource using an ordinary "new"
>>>>>> and a constructor with parameters. The sub-resources instance is no
>>>>>> more managed and injection is not available.
>>>>>>
>>>>>> Proposal: we need a way to pass an instance to a JAX-RS runtime to
>>>>>> inject dependencies.
>>>>>>
>>>>>> Btw. parameterless constructors are not enough - usually you are
>>>>>> going to pass some context from the main resource to the sub resources.
>>>>>>
>>>>>> See also: https://java.net/jira/browse/JAX_RS_SPEC-72
>>>>>>
>>>>>> thanks,
>>>>>>
>>>>>> adam
>>>>>
>>>>
>>>
>>>
>>> --
>>> Sergey Beryozkin
>>>
>>> Talend Community Coders
>>> http://coders.talend.com/
>>>
>>> Blog: http://sberyozkin.blogspot.com
>>
>
>
> --
> Sergey Beryozkin
>
> Talend Community Coders
> http://coders.talend.com/
>
> Blog: http://sberyozkin.blogspot.com