users@jersey.java.net

Re: [Jersey] Constructors vs Injection

From: Paul Sandoz <Paul.Sandoz_at_Sun.COM>
Date: Fri, 24 Apr 2009 11:58:45 +0200

Hi Charlie,

You can use @PostConstruct.

For example:

@Path("foo/{foo}")
public class FooResource extends BaseResource {
    private Foo foo;

    private @PathParam("foo") String name;

    @PostConstruct
    public void postConstruct() {
        this.foo = getStore().getFoo(name);
    }

    @GET
    @Produces("text/xml")
    public Response getHTML() { /* read foo */ }

    @PUT
    @Consumes("application/x-www-form-urlencoded")
    public void putForm(...) { /* update foo */ }
}

Paul.

On Apr 24, 2009, at 10:15 AM, Charles Brooking wrote:

> Hi all
>
> I've encountered a design issue relating to the use of @Context
> injection,
> and am wondering whether people had thoughts on this.
>
> I have several resource classes extending from a BaseResource class
> that
> includes some convenience methods. In this class I have used field
> injection rather than constructor injection to avoid duplication of
> arguments in the constructors of subclasses.
>
> public class BaseResource {
> @Context private HttpContext httpContext;
>
> public Store getStore() {
> return (Store) httpContext.getProperties().get("store");
> }
> }
>
> Now for the subclasses. In resource classes containing several
> methods, it
> seems convenient to put common initialisation code in the
> constructor. For
> example, both @GET and @PUT methods might require that an object is
> retrieved from some data store. Eg:
>
> @Path("foo/{foo}")
> public class FooResource extends BaseResource {
> private Foo foo;
>
> public FooResource(@PathParam("foo") String name) {
> this.foo = getStore().getFoo(name);
> }
>
> @GET
> @Produces("text/xml")
> public Response getHTML() { /* read foo */ }
>
> @PUT
> @Consumes("application/x-www-form-urlencoded")
> public void putForm(...) { /* update foo */ }
> }
>
> However, this fails because the getStore() method tries
> dereferencing the
> null pointer of httpContext. The HttpContext instance has not been
> injected yet, because the fields of the superclass are injected
> after the
> constructors complete.
>
> This problem has led me to think that perhaps this could be useful
>
> @Init
> public init(@PathParam("foo") String name) {
> getStore().getFoo(name); // will cause null pointer exception
> }
>
> where the "Init" method is called after dependencies are injected but
> before other methods are called.
>
> Have other people hit a similar design problem, and do you have
> different
> ideas?
>
> Later
> Charlie
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_jersey.dev.java.net
> For additional commands, e-mail: users-help_at_jersey.dev.java.net
>