users@jersey.java.net

Re: [Jersey] Spring, _at_Singleton resources and thread-safety

From: Jeff Schmidt <jas_at_535consulting.com>
Date: Mon, 13 Oct 2008 10:21:05 -0600

Hi Paul:

Thanks for such a speedy response. :) A point of clarification is
needed. Please below.

Congrats on the 1.0 release! We appreciate your efforts.

Cheers,

Jeff


On Oct 13, 2008, at 1:47 AM, Paul Sandoz wrote:

> Hi Jeff,
>
> On Oct 12, 2008, at 9:49 PM, Jeff Schmidt wrote:
>
>> Hello:
>>
>> I'm still going through all of the JSR 311 and Jersey
>> documentation, various blog posts, sample code etc. The main things
>> I need to nail down in a hurry is understanding resource life
>> cycles and integration with Spring. A further possible complication
>> is the project I'm working on is stuck with Spring 1.2 for the time
>> being (running in Tomcat 6.0.14). My understanding is that there is
>> more direct Spring integration for Jersey for Spring 2.0 and 2.5.
>> But, that won't help me. :)
>>
>
> You might have to write your own ComponentProvider if you need to
> support Spring 1.2 and the 2.0 support does not work for you.
>
>
>> There are numerous DAOs, services, data providers and whatnot
>> defined in the Spring application context. My JAX-RS resource
>> classes need to make use of these beans. It seems I need to create
>> singleton resources and configure them via Spring (again v 1.2).
>> This appears to have been done successfully for a small REST API
>> implemented using Jersey 0.6ea and the JerseySpringServlet class
>> defined a while back by Paul Sandoz at http://blogs.sun.com/sandoz/entry/integrating_jersey_and_spring_take
>> .
>>
>> There is only one root resource class, and it has the @Singleton
>> annotation. This class is configured via Spring, and things seems
>> to work okay. But, this API needs to be expanded significantly, and
>> I would like to incorporate sub-resource locators to make the
>> implementation more modular. In doing so, the sub-resource locator
>> classes will have their own Spring injected collaborators etc. I
>> would like to avoid defining all of the collaborators in the root
>> resource and provide them as constructor arguments to the sub-
>> resource locator classes. This way, the sub-locator classes can be
>> developed more independently.
>>
>
> You can inject ResourceContext:
>
> @Path("{id}")
> public SubResource getSubResource(@Context ResourceContext rc) {
> return rc.getResource(SubResource.class);
> }
>
> Or you can do:
>
> @Path("{id}")
> public Class<SubResource> getSubResource(@Context
> ResourceContext rc) {
> return SubResource.class;
> }
>
> If you just obtain the Spring injected reference to SubResource then
> Jersey will not perform injection onto the fields.

Will the above cause Jersey to instantiate the sub resource class
outside of Spring, or is this where the Spring prototype bean is
instantiated and setup by Spring, and then Jersey obtains the
reference and does its injection (e.g. in JerseySpringServlet)? How
about if I return the Spring injected (singleton) reference to
SubResource and code so I use only method parameter injection by
Jersey (no fields or constructor params)? Will that work? I assume
Jersey can see those annotations in the existing SubResource instance
and perform its injection?


>> In Paul's blog post, the difference between using Spring prototype
>> and singleton beans was demonstrated; but only as root resources.
>> How about as sub-resource locator classes? All of the examples
>> I've seen thus far show the root resource (singleton or not)
>> returning a newly constructed sub-resource locator instance,
>> providing already JAX-RS injected information via the constructor
>> arguments. I want to (Spring) inject my root resources with one or
>> more Spring configured sub-resource locator classes, and return
>> that instance rather than construct a new one per request.
>>
>> For singletons, the methods need to be thread-safe. Looking at
>> "Rules of Injection" at http://wikis.sun.com/display/Jersey/Overview+of+JAX-RS+1.0+Features
>> , it seems I can inject the request related information in the
>> individual methods of the sub-resource locator singleton, rather
>> than use field level injection, or pass that information via
>> constructor arguments.
>>
>
> Fields can be used on singletons as well for @Context related
> injection, but not for parameters.
>
> Parameters on constructors are problematic because in such cases
> Spring wants construct rather than Jersey. So in such cases avoid
> Jersey-specific stuff in constructors.
>
>
>> A simple example, using Jersey 0.8 in Netbeans 6.1.
>>
>> @Singleton
>> @Path("/exroot")
>> public class RootResource {
>>
>> //TODO: Inject via Spring
>> protected SubResource subResource = new SubResource();
>>
>> public RootResource() {
>> }
>>
>> @GET
>> @ProduceMime("text/plain")
>> public String getXml(
>> @Context UriInfo uriInfo,
>> @QueryParam("param") String param) {
>>
>> return "root, param: " + param;
>> }
>>
>> @Path("{id}")
>> public SubResource getSubResource() {
>> return subResource;
>> }
>> }
>>
>> @Singleton
>> public class SubResource {
>>
>> //TODO: Inject via Spring
>> protected String someSpringProperty = "propertyValue";
>>
>> public SubResource() {
>> }
>>
>> @GET
>> @ProduceMime("text/plain")
>> public String getXml(
>> @Context UriInfo uriInfo,
>> @PathParam("id") String id,
>> @QueryParam("param") String param) {
>>
>> return "sub-root, id: " + id + ", param: " + param;
>> }
>> }
>>
>> This example works as I'd expect in Netbeans, though I'm not yet
>> defining these beans in a Spring application context. But as far as
>> thread safety goes, does this make sense?
>
> Yes, again you can use @Context UriInfo on fields as well, Jersey
> will ensure the injected instance is thread safe.
>
>
>> By not using field level injection of request related information,
>> and instead assigning it to the methods of the resource or and sub-
>> resource locator classes, is thread safety ensured? Also, does
>> SubResource need the @Singleton annotation?
>>
>
> In your case, yes, as this synchronizes Jersey with the Spring scope.

Excellent. Thank you!

>
> Paul.
>
>> Thanks!
>>
>> Jeff
>> --
>> Jeff Schmidt
>> 535 Consulting
>> jas_at_535consulting.com
>> (408) 205-7697
>>
>>
>>
>>
>