本文介绍了如果注射器是儿童,Jersey-Guice不处理绑定资源?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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不处理绑定资源?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-10 20:44