Vicky Vicky - 3 months ago 17
reST (reStructuredText) Question

How to set an object to context so that i can get it anywhere in the application with @Context

I want to set

MyObject
class instance to the application context so that I can use it anywhere with the following:

@Context MyObject object


I used
Jedis
which gives me access for the
jedis
through the above approach.

Please help in setting the context.

I am using dropwizard (
jetty,jersery and jackson
).

Answer

I had some time and wrote up the way to do it (jersey only, no other DI framework used).

Jersey is compliant with javax.inject annotations. The reason you do NOT use a context annotation is because (by the sound of it) your MyObject class is not a context object (e.g. it doesn't change with each request like e.g. HttpServletRequest which is injectable). So we need to bind your object.

Consider my implementation of MyObject:

public class MyObject {

    String get() {
        return "I am an object"; 
    }
}

This object needs to be available in my jersey classes (resource, filter etc). I wrote a little resource using this bean:

@Path("context")
public class ContextResource {

    @Inject
    MyObject o;

    @GET
    public String get() {
        return o.get();
    }

}

Note that I am using the javax.inject.Inject annotation for this case to tell jersey I want this particular bean injected. All I need to do now is to tell jersey about this bean. In my DW application I do:

public class Application extends io.dropwizard.Application<Configuration>{  

    @Override
    public void run(Configuration configuration, Environment environment) throws Exception {

        environment.jersey().register(ContextResource.class);
        environment.jersey().register(new AbstractBinder() {

            @Override
            protected void configure() {
                bind(MyObject.class).to(MyObject.class);
            }
        });
    }

    public static void main(String[] args) throws Exception {
        new Application().run("server", "/home/artur/dev/repo/sandbox/src/main/resources/config/test.yaml");
    }
}

Note that I am using a binder to bind my bean. The syntax looks funky, but essentially it is doing a "bind the type to the implementation". Since my type is my implementation (I am not using an interface for MyObject), this looks like:

bind(MyObject.class).to(MyObject.class) 

Now jersey knows about my bean and will happily inject it.

Running all my code prints:

artur@pandaadb:~/dev/vpn$ curl localhost:9085/api/context
I am an object

Hope that brings some insights on how to use injection without a framework. Personally I would recommend using guice with dropwizard (google: dropwizard-guicey) which makes these kind of things very easy.

Regards,

Artur

Comments