【问题标题】:Jersey-Guice doesn't process bound resources if injector is a child?如果注射器是孩子,Jersey-Guice 不会处理绑定资源?
【发布时间】:2011-12-10 05:28:02
【问题描述】:

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

任何想法为什么会发生这种情况?两个版本如下所示。

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

如果有更好的方法在应用程序注入器和 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);
             }
         });
     }
 }

【问题讨论】:

    标签: java jersey guice


    【解决方案1】:

    在调试器玩了一阵子之后,我想通了。

    通过迭代注入器的绑定来发现资源,检查那些是资源或提供者。使用的注入器通过如下构造函数注入到 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);
                 }
             });
         }
     }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-09-29
      • 2016-05-07
      • 1970-01-01
      • 2015-07-28
      • 2014-02-20
      • 1970-01-01
      • 2012-07-21
      相关资源
      最近更新 更多