如果注射器是儿童,Jersey-Guice不处理绑定资源?

Dav*_* B. 3 java jersey guice

我正在使用Jersey-Guice来配置Jersey应用程序,遵循此模板.如果InjectorGuiceServletContextListener.getInjector()方法返回的,则一切正常Guice.createInjector().如果该注入器是另一个注入器的子进程,那么绑定的资源(例如,MyResource在下面的代码中)永远不会被添加到Jersey ResourceConfig和Jersey崩溃,并且抱怨缺少根资源.我不认为绑定的资源甚至被扫描,因为通常的"INFO:将my.example.MyResource注册为根资源类"不会出现在日志中.

任何想法为什么会这样?两个版本如下所示.

另外一个问题:我正在尝试使用子注入器,因为我想在Main()类中配置我的应用程序数据服务对象.不仅仅是泽西岛资源需要访问它.我仍然需要将它注入Jersey资源.

如果有更好的方法在应用程序Injector和servlet注入器之间共享应用程序单例(比我当前的servlet注入器作为应用程序注入器的子进程的方法更好),请告诉我.

这个版本有效.

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);
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

以下代码不起作用.

 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);
             }
         });
     }
 }
Run Code Online (Sandbox Code Playgroud)

Dav*_* B. 5

我在调试器玩得很开心之后想出来了.

通过迭代注入器的绑定,检查那些资源或提供者来发现资源.使用的注入器通过如下构造函数注入GuiceContainer : public GuiceContainer(@Inject injector). 由于没有对子注入器中指定的GuiceContainer.class进行显式绑定,因此使用父(即根)注入器来创建实例(我猜是即时绑定),因此父(而不是子)注入器是注入到GuiceContainer实例中.

修复很简单:

在子注入器中显式绑定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() {
                 /* 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);
             }
         });
     }
 }
Run Code Online (Sandbox Code Playgroud)