Jersey 和 Google Guice 的集成

我的问题是:为什么在创建部署在某种 servlet 容器(如 jetty 或 tomcat)上的应用程序时,我需要在执行 JavaSE 应用程序和 ServletModule 时创建 AbstractModule?它们之间有什么区别?

My question is: why do I need to create AbstractModule when doing JavaSE application and ServletModule while creating application that is deployed on some kind of servlet container like jetty or tomcat? What are the differences between them?

我需要将 Jersey 与 Guice 集成.是否有必要为泽西岛注册 Guice 的存在才能以某种方式使用它?我不能只启用注入并在我想要的任何地方执行它们(普通类、过滤器、处理程序、服务、DAO 等)吗?为什么我不能像在 JavaSE 应用程序中那样只配置 guice,而是需要使用 ServletModule?

I need to integrate Jersey with Guice. Is it necessary to register presence of Guice for Jersey to use it somehow? Can't I just enable injections and do them everywhere I want (normal classes, filters, handlers, services, DAOs etc.)? And why can't I just configure guice like in JavaSE application, but instead need to use ServletModule?

据我在网上看到,Guice 使用 HK2 服务的例子很多,反之亦然,所以我认为它很重要吗?(有必要吗?)

As far as I see on web, there are many examples of using HK2 services by Guice and vice versa, so I can consider it as important? (necessary?)

谢谢

推荐答案

AbstractModule 是 Guice 引导(配置)阶段的基本构建块.你总是需要其中的一个或多个.另一方面,ServletModule 是一种专业化,可以为您进行一些配置,因为它在 servlet 容器中运行.

An AbstractModule is the basic building block of the bootstrap (configuration) phase of Guice. You always need one or more of that. On the other hand a ServletModule is an specialization which does some configuration for you given the fact that it is running in a servlet container.

来自 Guice 文档:

此模块设置请求和会话范围,并提供一个配置过滤器和 servlet 的地方.

This module sets up the request and session scopes, and provides a place to configure your filters and servlets from.

关于 Guice-Jersey 集成,您当然需要进行设置.它不会突然出现.Guice 与任何其他依赖注入框架一样,在它可以控制构建您的对象 时工作.如有疑问,请问问自己是谁创建了对象.

About the Guice-Jersey integration you certainly need to set it up. It won't work out of the blue. Guice, as any other dependency injection framework, works when it has the control of building your objects. When in doubt ask yourself who creates the object.

对于 Jersey 和一般的 JAX-RS,谁来创建对象?不是你,你只是定义它们.容器创建它们.JAX-RS 运行时.在您的情况下,泽西运行时.Jersey 内部使用 HK2 依赖注入框架.因此,您需要桥接这两个框架,以便注入您使用一些 Guice 资源定义的 JAX-RS 类.或者反过来!这就是为什么有一个 HK2-guice 网桥的原因.因此,Jersey 将使用 HK2 构建您的对象,并且 HK2 也会在 Guice 上查找您的资源,这要归功于桥.

With Jersey, and JAX-RS in general, who creates the objects? Not you, you just define them. The container creates them. The JAX-RS runtime. In your case, the Jersey runtime. And Jersey uses internally the HK2 dependency injection framework. So you need to bridge both those frameworks in order to inject a JAX-RS class you have defined with some Guice resources. Or the other way around! That is the reason why there is a HK2-guice bridge. So Jersey would build your objects using HK2 and HK2 will look up your resources also on Guice thanks to the bridge.

一个简单的例子.我使用这段代码来初始化一个 REST API我想在哪里注入 Guice 资源.

A simple example. I use this code to initialize a REST API where I want to inject Guice resources.

@ApplicationPath("api")
public class ApiRest extends ResourceConfig {  
    private static final Logger log = LoggerFactory.getLogger(ApiRest.class);

    @Inject
    public ApiRest(ServiceLocator serviceLocator, ServletContext servletContext) {
        log.debug("Inicialitzant Jersey.");
        packages("net.sargue.app.api");

        GuiceBridge.getGuiceBridge().initializeGuiceBridge(serviceLocator);
        GuiceIntoHK2Bridge guiceBridge = serviceLocator.getService(GuiceIntoHK2Bridge.class);
        Injector injector = (Injector) servletContext.getAttribute(Injector.class.getName());
        if (injector == null)
            throw new RuntimeException("Guice Injector not found");
        guiceBridge.bridgeGuiceInjector(injector);
    }
}

请注意,上面的示例需要注册 ServletModule,因为它从 ServletContext 中提取 Guice 注入器.或者您可以将注入器添加到其他地方的 ServletContext 中.或者只是在初始化 REST API 时创建注入器,这取决于您的偏好和应用程序.

Please note that the above example needs the ServletModule registered as it pulls the Guice injector from the ServletContext. Or you can just add the injector to the ServletContext somewhere else. Or just create the injector when initializing the REST API, it depends on your preferences and the application.

相关文章