users@jersey.java.net

Spring, _at_Singleton resources and thread-safety

From: Jeff Schmidt <jas_at_535consulting.com>
Date: Sun, 12 Oct 2008 13:49:02 -0600

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

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.

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.

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? 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?

Thanks!

Jeff
--
Jeff Schmidt
535 Consulting
jas_at_535consulting.com
(408) 205-7697