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