Java – using Jersey’s dependency injection

If I use Jersey 1.12, and I have multiple resource classes, and they all need to access some shared context, what is the best way to inject dependencies, whether in the constructor of the resource class or in the handler method? Do I need to use an external Di library, or what is built into Jersey?

Maybe foos's resources look like this:

package com.example.resource;

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;

@Path("/some/api/path/foo")
public class FooResource
{
    @GET
    @Produces("text/html")
    public String getFoo(@QueryParam("id") String id)
    {
        Foo foo = /* get a Foo from some shared context based on id */
        /* Process foo into a String */
    }
}

And bars:

package com.example.resource;

import javax.ws.rs.GET;
import javax.ws.rs.Produces;
import javax.ws.rs.Path;

@Path("/some/api/path/bar")
public class BarResource
{
    @GET
    @Produces("text/html")
    public String getBar(@QueryParam("id") String id)
    {
        Bar bar = /* get a Bar from some shared context based on id */
        /* Process bar into a String */
    }
}

Solution

I finally used Google Guice, a lightweight Di framework that integrates well with Jersey That's what I have to do:

First, I'm in POM Dependency added to XML:

<dependency>
        <groupId>com.google.inject</groupId>
        <artifactId>guice</artifactId>
        <version>3.0</version>
        <scope>compile</scope>
    </dependency>
    <dependency>
        <groupId>com.sun.jersey.contribs</groupId>
        <artifactId>jersey-guice</artifactId>
        <version>1.12</version>
        <scope>compile</scope>
    </dependency>

I want to implement Dao as a singleton with interface:

public interface MySingletonDao
{
    // ... methods go here ...
}

And specific implementation:

@Singleton
public class ConcreteMySingletonDao implements MySingletonDao
{
    // ... methods go here ...
}

Decorate the resource class like this:

@Path("/some/path")
@RequestScoped
public class MyResource
{
    private final MySingletonDao mySingletonDao;

    @Inject
    public MyResource(MySingletonDao mySingletonDao)
    {
        this.mySingletonDao = mySingletonDao;
    }

    @POST
    @Produces("application/json")
    public String post() throws Exception
    {
            // ... implementation goes here ...
    }
}

Created a class that will perform binding:

public class GuiceConfig extends Guiceservletcontextlistener
{
    @Override
    protected Injector getInjector()
    {
        return Guice.createInjector(new JerseyServletModule()
        {
            @Override
            protected void configureServlets()
            {
                bind(MyResource.class);
                bind(AnotherResource.class);
                bind(MySingletonDao.class).to(ConcreteMySingletonDao.class);
                serve("/*").with(GuiceContainer.class);
            }
        });
    }
}

I use jetty instead of GlassFish to actually act as a server In my functional test, it looks like:

private void startServer() throws Exception
{
    this.server = new Server(8080);
    ServletContextHandler root =
        new ServletContextHandler(server,"/",ServletContextHandler.SESSIONS);

    root.addEventListener(new GuiceConfig());
    root.addFilter(GuiceFilter.class,"/*",EnumSet.of(DispatcherType.REQUEST));
    root.addServlet(EmptyServlet.class,"/*");

    this.server.start();
}

Emptyservlet is the sample code from sunny Gleason, which is given as the answer: https://stackoverflow.com/a/3296467 – my original

root.addServlet(new ServletHolder(new ServletContainer(new PackagesResourceConfig("com.example.resource"))),"/*");

Not a line

root.addServlet(EmptyServlet.class,"/*");

However, this causes Jersey to try to perform dependency injection instead of Guice, which will lead to runtime errors

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>