users@jersey.java.net

[Jersey] Re: Seeking best practice in lifecycle management of web service objects using Jersey + Spring integration

From: David Sean Taylor <david_at_bluesunrise.com>
Date: Wed, 7 Dec 2011 18:24:16 -0800

To take an example similar to yours, I tried to figure out how to inject @Context params into the constructors of classes annotated by Spring's @Component. Say we had a resource class:

@Component @Scope("request")
public class MyResource {
        
        public MyResource() {} // default constructor required by Spring (you don't need to declare this)

If I tried to add a constructor injected with JAX-RS contexts:

      protected final ServletContext servletContext;
      protected final HttpServletRequest httpServletRequest;
      protected final UriInfo uriInfo;

      public MyResource(@Context ServletContext, @Context HttpServletRequest httpServletRequest, @Context UriInfo uriInfo) {
                this.servletContext = servletContext;
                this.httpServletRequest = httpServletRequest;
                this.uriInfo = uriInfo;
       }

This approach failed at runtime, since Spring wants to use the default constructor. Using annotations, Im not sure if there is a way to even get this to work. If you don't mind setter dependency injection, JAX-RS handled the request-scoped dependency injection for me without much fuss:

@Component @Scope("request")
public class MyResource {
  
      @Context
      protected final ServletContext servletContext;
      @Context
      protected final HttpServletRequest httpServletRequest;
      @Construct
      protected final UriInfo uriInfo;

      // go with default constructor for Spring

On Dec 7, 2011, at 12:04 PM, Mark Petrovic wrote:

> Good day.
>
> I have a lot of pleasant experience writing Jersey based web services
> that do not also use Spring DI.
>
> The way I traditionally made things like ServletContext and
> HttpServletRequest available to my resource classes was to define an
> abstract resource base class whose ctor took this objects as
> arguments. For example, here is such a base class ctor:
>
> protected AbstractResource(@Context ServletContext servletContext,
> @Context HttpServletRequest httpServletRequest, @Context UriInfo
> uriInfo) {
> ...
> }
>
> Classes that extend this AbstractResource can then use the
> servletContext, e.g., in whatever way they see fit.
>
> However, I have recently inherited Jersey web service code that uses
> Spring DI, more specifically, resource classes marked with @Component
> with the Spring default Singleton scope.
>
> My question is this: What is the best practice for acquiring
> request-based references to things like the ServletContext (not
> request-based, but no matter) and HttpServletRequest in this new
> regime of Spring managed resource class lifecycle?
>
> I have seen examples whereby, e.g., the HttpServletRequest is acquired
> via an "@Context HttpServletRequest request" argument to the resource
> class method handling a specific request. However, I'm not thrilled
> with this, as every method that needs these @Context references must
> include them in their method signature, which is an almost immediate
> violation of the DRY principle.
>
> I have also seen mentioned a configuration of the Spring container
> whereby Singleton beans can be produced that contain beans with
> per-request lifecycles. Frankly, I'm not thrilled with this, either,
> as in many months down the road, I may forget how this actually works,
> and will have to relearn how and why it works.
>
> Would someone be kind enough to talk about how they've handled this.
> I may not have the freedom to change the lifecycle of the resources
> classes from Singleton to request-scope ("prototype", I believe).
> Even if I do, I still want to understand what best practice surround
> this issue for the case of Singleton resource classes handling
> per-request underlying servlet objects.
>
> Thank you very kindly.
> Mark
>
> --
> Mark