我很擅长使用Jersey 2创建REST Web服务。我现在能够得到一些简单的案例,我现在正在转向"真正的"工作
我创建自己的reshape2
实例,并使用Guice返回的REST控制器实例填充ResourceConfig
个实例:
ResourceConfig
请注意,由于这些REST控制器实例是由Guice提供的,因此实例将填充所有必需的依赖项,这些依赖项都标有<!-- language: lang-java -->
final ResourceConfig rc = new ResourceConfig();
//register an *instance* of a REST controller
rc.register(injector.getInstance(MyRestController.class));
注释。
但是,当我运行上面的代码来引导Jersey时,我看到如下错误:
@Inject
显然正在发生的事情是,泽西岛还试图解析REST控制器实例上的org.glassfish.hk2.api.UnsatisfiedDependencyException: There was no object available for injection at SystemInjecteeImpl(....
依赖关系,因为它看到了与Guice相同的@Inject
注释。
我不希望泽西岛做任何依赖注入。我认为从Jersey到Guice都有桥梁,但根据我无法在此处显示的程序要求,我需要自己创建REST控制器实例并向Guice @Inject
询问它们。
我的问题:如何在Jersey中禁用依赖注入?
我目前正在使用Injector
注释。也许我可以使用javax.inject.Inject
注释,认为泽西岛不会寻找这些注释。但是,我宁愿只关闭泽西岛的依赖注入。我怎么能这样做?
谢谢!
答案 0 :(得分:2)
首先,您的解决方案:
public class GuiceJerseyManualBridge extends io.dropwizard.Application<Configuration> {
@Override
public void run(Configuration configuration, Environment environment) throws Exception {
JerseyEnvironment jersey = environment.jersey();
// create the Guice env and its dependencies
Injector i = Guice.createInjector(new AbstractModule() {
@Override
protected void configure() {
Map<String, String> props = new HashMap<>();
props.put("testme", "Hello World Guice Inject Test");
Names.bindProperties(binder(), props);
bind(HelloResource.class).in(Singleton.class);
}
});
// get instance
HelloResource resourceInstance = i.getInstance(HelloResource.class);
jersey.register(new AbstractBinder() {
@Override
protected void configure() {
// teach jersey about your guice dependency
bind(resourceInstance).to(HelloResource.class);
}
});
jersey.register(HelloResource.class); // register resource - jersey will discover this from the binding
}
@Override
public void initialize(Bootstrap<Configuration> bootstrap) {
super.initialize(bootstrap);
}
public static void main(String[] args) throws Exception {
new GuiceJerseyManualBridge().run("server", "/home/artur/dev/repo/sandbox/src/main/resources/config/test2.yaml");
}
@Path("test")
@Produces(MediaType.APPLICATION_JSON)
public static class HelloResource {
@Inject
@Named("testme")
private String testString;
public HelloResource() {
System.err.println("I am created now");
}
@GET
@Path("test")
public String test(String x) {
return testString;
}
}
}
请忽略我的DropWizard设置。它使用Jersey并使用Guice,因此注册部分是相同的。
你在这里遇到两个困境:
所以,我上面的解决方案做了以下事情:
将Guice bean绑定到平针织环境。这将使球衣找到您创建的bean。由于它绑定到泽西环境中,它不会尝试重新初始化bean,而是将其视为完全有效的对象。 为此,您需要将Resource注册为类参数(触发jersey以搜索已注册的bean,或者根据需要创建一个)
您可以做的另一个解决方案是将Injects移动到构造函数(通常是避免现场注入的好习惯)。因为您注册了一个对象,所以再次调用构造函数是非法的。因此,球衣不会尝试进行任何注射(因为没有任何事情可做)
最后,我不知道您的要求是如何工作的,但您想要做的主要是手动创建Guice-Jersey Bridge。以你演示的方式教你的豆子到球衣上的确是Guice-Jersey桥的作用,除了它修复了所有那些小边缘的情况(就像你现在看到的那样)。强烈建议您实施该桥接器。
这个桥的作用实际上就是简单地将bean的创建委托给guice。这意味着它将(1)向一个实例请求guice然后自己创建一个(如果Guice没有返回实例)。
Hiope有帮助,
干杯!阿图尔