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

时间:2011-12-10 05:28:03

标签: java jersey guice

我正在使用Jersey-Guice配置Jersey应用,遵循此template。如果Injector方法返回的GuiceServletContextListener.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);
            }
        });
    }
}

以下代码不起作用。

 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);
             }
         });
     }
 }

1 个答案:

答案 0 :(得分: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);
             }
         });
     }
 }