java - Guice 不会注入(inject) Jersey 的资源

标签 java rest dependency-injection jersey guice

在整个互联网上进行了解析,但无法弄清楚为什么会发生这种情况。我有一个带有 Jersey 资源的最简单的项目(通过 jersey-quickstart-grizzly2 原型(prototype))。我将 Guice 用作 DI,因为 CDI 也不想与 Jersey 合作。问题是 Guice 在注入(inject) Jersey 的资源时无法解析要使用的类。它在外面很好用,但不适用于 Jersey 。
这是 Jersey 资源:

import com.google.inject.Inject;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("api")
public class MyResource {

    private Transport transport;

    @Inject
    public void setTransport(Transport transport) {
        this.transport = transport;
    }

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getIt() {
        return transport.encode("Got it!");
    }
}

传输接口(interface):
public interface Transport {
    String encode(String input);
}

它的实现:
public class TransportImpl implements Transport {
    @Override
    public String encode(String input) {
        return "before:".concat(input).concat(":after");
    }
}

按照 Google 的入门手册,我继承了 AbstractModule并像这样绑定(bind)我的类(class):
public class TransportModule extends AbstractModule {
    @Override
    protected void configure() {
        bind(Transport.class).to(TransportImpl.class);
    }
}

我得到注入(inject)器 main()有了这个,但在这里并不需要它:
Injector injector = Guice.createInjector(new TransportModule());

顺便说一句,当我尝试这样做时没有问题:
Transport transport = injector.getInstance(Transport.class);

最佳答案

Jersey 2 已经有一个 DI 框架,HK2 .你可以使用它,或者如果你愿意,你可以使用 HK2/Guice 桥接你的 Guice 模块和 HK2。
如果你想使用 HK2,在最基本的层面上,它与 Guice 模块没有太大区别。例如,在您当前的代码中,您可以这样做

public class Binder extends AbstractBinder {
    @Override
    public void configurer() {
        bind(TransportImpl.class).to(Transport.class);
    }
}
然后只需在 Jersey 注册活页夹
new ResourceConfig().register(new Binder());
一个区别是绑定(bind)声明。在 Guice 中,它“将合约绑定(bind)到实现”,而在 HK2 中,它是“将实现与合约绑定(bind)”。您可以看到它与 Guice 模块相反。
如果你想在 Guice 和 HK2 之间架起桥梁,那就稍微复杂一点。你需要对HK2多了解一点。这是一个如何让它工作的例子
@Priority(1)
public class GuiceFeature implements Feature {

    @Override
    public boolean configure(FeatureContext context) {
        ServiceLocator locator = ServiceLocatorProvider.getServiceLocator(context);
        GuiceBridge.getGuiceBridge().initializeGuiceBridge(locator);
        Injector injector = Guice.createInjector(new TransportModule());
        GuiceIntoHK2Bridge guiceBridge = locator.getService(GuiceIntoHK2Bridge.class);
        guiceBridge.bridgeGuiceInjector(injector);
        return true;
    }
} 
然后注册功能
new ResourceConfig().register(new GuiceFeature());
就个人而言,如果您要使用 Jersey ,我建议您熟悉 HK2。
另见:
  • HK2 Documentation
  • Custom Injection and Lifecycle Management

  • 更新
    抱歉,我忘记添加要使用 Guice Bridge,您需要依赖。
    <dependency>
        <groupId>org.glassfish.hk2</groupId>
        <artifactId>guice-bridge</artifactId>
        <version>2.4.0-b31</version>
    </dependency>
    
    请注意,这是 Jersey 2.22.1 的依赖项。如果您使用不同版本的 HK2,则应确保使用与您的 Jersey 版本相同的 HK2 版本。

    关于java - Guice 不会注入(inject) Jersey 的资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35085267/

    相关文章:

    java - 如何从现有的 Unix 服务器连接连接到 FTP 服务器?

    java - IntelliJ IDEA 13 + Tomcat 7 部署

    java - 重写 Hashtable.contains() java 时出现 StackOverflowError

    javascript - 使用 Mountebank,冒名顶替者是否有可能在向客户端返回响应后执行某些逻辑?

    Java CDI : How to change producers at runtime using qualifiers with multiple values?

    c# - Repository不能作为泛型方法中的类型参数

    java - 将 Java 代码用于 Android 应用程序(用于 AES 加密)

    node.js - 具有 Oracle 数据库持久性的 ActionHero.js 框架

    java - 是否可以从 Microsoft Graph 检索 "Contact Presence"?

    c# - 在 Provider Ninject 中检索自定义绑定(bind)参数