2011-12-10 1 views
2

私はJersey-Appを設定するためにJersey-Guiceを使用していますが、これに続いてtemplateです。 GuiceServletContextListener.getInjector()メソッドによって返されたInjectorGuice.createInjector()によって作成された場合、すべて正常に動作します。そのインジェクタが別のインジェクタの子である場合、バインドされたリソース(たとえば、コード内のMyResource)はジャージーResourceConfigに追加されず、Jerseyはルートリソースの欠落に関する苦情を受けてクラッシュします。通常の「INFO:ルートリソースクラスとしてのmy.example.MyResourceの登録」がログに表示されないため、バインドされたリソースがスキャンされるとは思われません。インジェクタが子供の場合、Jersey-Guiceはバインドされたリソースを処理しませんか?

これはなぜ起こっているのでしょうか?どちらのバージョンも以下のとおりです。

その他の質問:メイン()クラスでアプリケーションデータサービスオブジェクトを構成したいので、私は子インジェクタを使用しようとしています。ジャージーのリソースだけでは、それにアクセスする必要があります。私はまだジャージーの資源に注入する必要があります。

アプリケーションインジェクタとサーブレットインジェクタの間でアプリケーションシングルトンを共有する方が良い場合は、私の現在のアプローチであるサーブレットインジェクタがアプリケーションインジェクタの子であるよりも優れています。

このバージョンが動作します。

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

答えて

4

私はデバッガで楽しく学んだ。

リソースは、インジェクタのバインディングを反復し、リソースまたはプロバイダであるものを確認することによって検出されます。使用されたインジェクタは、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); 
      } 
     }); 
    } 
} 
関連する問題