在Guice容器中运行Jersey

整合思路

Jersey本身是基于Servlet架构的,Guice自身提供了Servlet管理支持,如果把Jersey的Servlet放入到Guice中管理,两者就可以很好的融合在一起。(以下使用的为Jetty容器,其它的容器也是相似的原理)。

配置Maven

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<dependencies>
<dependency>
<groupid>org.eclipse.jetty</groupid>
<artifactid>jetty-servlet</artifactid>
<version>${jetty.version}</version>
</dependency>
<dependency>
<groupid>com.google.inject</groupid>
<artifactid>guice</artifactid>
<version>${guice.verion}</version>
</dependency>
<dependency>
<groupid>com.sun.jersey</groupid>
<artifactid>jersey-server</artifactid>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupid>com.sun.jersey.contribs</groupid>
<artifactid>jersey-guice</artifactid>
<version>${jersey.version}</version>
</dependency>
<dependency>
<groupid>junit</groupid>
<artifactid>junit</artifactid>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>

示例程序

创建一个简单的POJO接口,用于注入到Jersey的服务中。

1
2
3
public interface GuicyInterface {
String get();
}

创建以上接口的实现类。

1
2
3
4
5
public class GuicyInterfaceImpl implements GuicyInterface {
public String get() {
return GuicyInterfaceImpl.class.getName();
}
}

创建JAX-RS服务类,并且注入了上述的POJO接口。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.QueryParam;
import com.google.inject.Inject;
@Path("/helloguice")
public class HelloGuice {
private final GuicyInterface gi;
@Inject
public HelloGuice(final GuicyInterface gi) {
this.gi = gi;
}
@GET
@Produces("text/plain")
public String get(@QueryParam("x") String x) {
return "Howdy Guice. " + "Injected impl " + gi.toString() + ". Injected query parameter "+ (x != null ? "x = " + x : "x is not injected");
}
}

初始化Guice的依赖注入容器,绑定上述的接口和实现类,这里使用了JerseyServletModule,JerseyServletModule是ServletModule的子类,专门用来初始化JerseyServlet的依赖。Servlet使用的是GuiceContainer,它是ServletContainer的子类,ServletContainer就是Jersey的dispatcher Servlet。初始化的方式是使用Listener,这也是其它容器的常规初始化方式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
import com.google.inject.Guice;
import com.google.inject.Injector;
import com.google.inject.servlet.GuiceServletContextListener;
import com.sun.jersey.guice.JerseyServletModule;
import com.sun.jersey.guice.spi.container.servlet.GuiceContainer;
public class HelloGuiceServletConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new JerseyServletModule() {
@Override
protected void configureServlets() {
// Must configure at least one JAX-RS resource or the
// server will fail to start.
bind(HelloGuice.class);
bind(GuicyInterface.class).to(GuicyInterfaceImpl.class);
// Route all requests through GuiceContainer
serve("/*").with(GuiceContainer.class);
}
});
}
}

启动Jetty服务。如果使用其他容器,比如使用tomcat,可以直接在web.xml 文件中配置 HelloGuiceServletConfig Listener。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.DefaultServlet;
import org.eclipse.jetty.servlet.ServletContextHandler;
import com.google.inject.servlet.GuiceFilter;
public class GuiceLauncher {
public static void main(String[] args) throws Exception {
// 创建服务器.
Server server = new Server(8080);
// 创建Servlet上下文,添加Jersey Servlet
ServletContextHandler sch = new ServletContextHandler(server, "/");
//添加 Guice listener,包含所有的依赖配置
sch.addEventListener(new HelloGuiceServletConfig());
// 添加 GuiceFilter,路由所有请求
sch.addFilter(GuiceFilter.class, "/*", null);
sch.addServlet(DefaultServlet.class, "/");
// Start the server
server.start();
server.join();
}
}

1
测试地址: http://localhost:8080/helloguice?x=q

参考《Guice 之 Servle