Sha*_*rog 6 java dependency-injection jersey java-ee
如果我使用Jersey 1.12,并且我有多个资源类,并且它们都需要访问一些共享上下文,那么注入依赖项的最佳方法是什么,无论是在资源类的构造函数中还是在处理程序方法中?我是否需要使用外部DI库,或者Jersey内置了什么?
也许Foos的资源看起来像这样:
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 */
}
}
Run Code Online (Sandbox Code Playgroud)
和酒吧:
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 */
}
}
Run Code Online (Sandbox Code Playgroud)
Sha*_*rog 12
我最终使用了Google Guice,这是一个轻量级的DI框架,可以很好地与Jersey集成.这就是我必须做的事情:
首先,我在pom.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>
Run Code Online (Sandbox Code Playgroud)
我希望将DAO实现为具有接口的单例:
public interface MySingletonDao
{
// ... methods go here ...
}
Run Code Online (Sandbox Code Playgroud)
和具体的实施:
@Singleton
public class ConcreteMySingletonDao implements MySingletonDao
{
// ... methods go here ...
}
Run Code Online (Sandbox Code Playgroud)
像这样装饰资源类:
@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 ...
}
}
Run Code Online (Sandbox Code Playgroud)
创建了一个将执行绑定的类:
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);
}
});
}
}
Run Code Online (Sandbox Code Playgroud)
我使用Jetty而不是Glassfish来实际充当服务器.在我的功能测试中,它看起来像:
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();
}
Run Code Online (Sandbox Code Playgroud)
在EmptyServlet来自给出了一个答案,在欣格里森的示例代码:/sf/answers/230752721/ -我本来
root.addServlet(new ServletHolder(new ServletContainer(new PackagesResourceConfig("com.example.resource"))), "/*");
Run Code Online (Sandbox Code Playgroud)
而不是线
root.addServlet(EmptyServlet.class, "/*");
Run Code Online (Sandbox Code Playgroud)
但是这导致Jersey尝试执行依赖注入而不是Guice,这会导致运行时错误.