问题描述
我正在使用Jersey-Guice来配置Jersey应用程序,遵循此。如果 GuiceServletContextListener.getInjector()
方法返回的 Injector
由创建,则一切正常Guice.createInjector()
。如果该注入器是另一个注入器的子节点,则绑定资源(例如,下面代码中的 MyResource
)永远不会添加到Jersey ResourceConfig
和泽西岛因失去根资源而抱怨。我不认为绑定的资源甚至被扫描,因为通常的INFO:将my.example.MyResource注册为根资源类不会出现在日志中。
I'm using Jersey-Guice to configure a Jersey app, following this template. Everything works fine if the Injector
returned by the GuiceServletContextListener.getInjector()
method is created by Guice.createInjector()
. If that injector is instead the child of another injector, then the bound resources (e.g., MyResource
in the code below) are never added to the Jersey ResourceConfig
and Jersey crashes with a complaint about missing root resources. I don't think the bound resources are even scanned, because the usual "INFO: Registering my.example.MyResource as a root resource class" doesn't appear in the log.
为什么会发生这种情况的任何想法?两个版本都显示如下。
Any ideas why this might be happening? Both versions are show below.
作为一个额外的问题:我正在尝试使用子注入器,因为我想在我的Main()中配置我的应用程序数据服务对象类。不仅仅是泽西岛资源需要访问它。我仍然需要将它注入Jersey资源。
As an additional question: I'm trying to use the child injector because I want to configure my application data service object in my Main() class. More than just the Jersey resources need access to it. I still need it injected into the Jersey resources.
如果有更好的方法在应用程序Injector和servlet注入器之间共享应用程序单例(比我作为应用程序注入器子代的servlet注入器的当前方法更好) ,请告诉我。
If there's a better way to share the application singleton between the application Injector and servlet injector (better than my current approach of the servlet injector being a child of the application injector), please let me know.
此版本有效。
public class MyConfig extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(new ServletModule() {
@Override
protected void configureServlets() {
bind(MyResource.class);
serve("*").with(GuiceContainer.class);
}
});
}
}
以下代码不起作用。
public class MyConfig extends GuiceServletContextListener {
final Injector parentInjector;
public MyConfig(Injector injector) {
this.parentInjector = injector;
}
@Override
protected Injector getInjector() {
return parentInjector.getChildInjector(new ServletModule() {
@Override
protected void configureServlets() {
bind(MyResource.class);
serve("*").with(GuiceContainer.class);
}
});
}
}
推荐答案
我在使用调试器获得一些乐趣后想出来。
I figured it out after some fun with the debugger.
通过迭代注入器的绑定来检测资源,检查那些资源或提供者。使用的注入器通过如下构造函数注入GuiceContainer: public GuiceContainer(@Inject injector)
。由于没有对子注入器中指定的GuiceContainer.class进行显式绑定,因此父(即根)注入器用于创建实例(我估计实时绑定),因此父(而不是子)注入器是注入GuiceContainer实例。
The resources are discovered by iterating over the bindings of the injector, checking for those that are resources or providers. The injector used is injected into the GuiceContainer via a constructor like this: public GuiceContainer(@Inject injector)
. With no explicit binding for GuiceContainer.class specified in the child injector, the parent (i.e., root) injector is used to create the instance (just-in-time binding, I guess) and consequently the parent (not the child) injector is injected into to the GuiceContainer instance.
修复很简单:
明确地绑定子注入器中的GuiceContainer.class。以下代码有效
Explicitly bind GuiceContainer.class in the child injector. The following code works
public class MyConfig extends GuiceServletContextListener {
final Injector parentInjector;
public MyConfig(Injector injector) {
this.parentInjector = injector;
}
@Override
protected Injector getInjector() {
return parentInjector.getChildInjector(new ServletModule() {
@Override
protected void configureServlets() {
/* Explicitly bind GuiceContainer so that
* the child, not root, injector is injected
* into its constructor. */
bind(GuiceContainer.class);
bind(MyResource.class);
serve("*").with(GuiceContainer.class);
}
});
}
}
这篇关于如果注射器是儿童,Jersey-Guice不处理绑定资源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!