PrivateModule
PrivateModuleを使うと、モジュールに登録されたコンポーネントの公開/非公開を制御できます。
- デフォルトは非公開。
Injector injector = Guice.createInjector( new PrivateModule(){ // ↑PrivateModuleを派生 protected void configure() { // コンポーネントを登録 // → 登録しただけでは非公開で外部から参照できない。 binder().bind( String.class ).toInstance( "mii" ); binder().bind( Integer.class ).toInstance( 100 ); // 公開するには、明示的にexposeする。 expose( Integer.class ); } }); // exposeされたコンポーネントは取得可能 System.out.println( injector.getInstance( Integer.class ) ); // そうでないものは、取得できずエラーになる。 try { System.out.println( injector.getInstance( String.class ) ); } catch ( Exception e ) { e.printStackTrace(); }
実行結果です。
100 com.google.inject.ConfigurationException: Guice configuration errors: 1) A binding to java.lang.String already exists on a child injector. while locating java.lang.String 1 error at com.google.inject.InjectorImpl.getProvider(InjectorImpl.java:784) at com.google.inject.InjectorImpl.getProvider(InjectorImpl.java:743) at com.google.inject.InjectorImpl.getInstance(InjectorImpl.java:793) at guice.PrivateModuleSmple.main(PrivateModuleSmple.java:43)
非公開のコンポーネントは外部に公開されないので、他のモジュールと設定が競合していてもエラーになりません。
Injector injector = Guice.createInjector( new PrivateModule(){ protected void configure() { binder().bind( String.class ).toInstance( "foo" ); // モジュール内の他のコンポーネントでは使用できる binder().bind( Foo.class ); expose( Foo.class ); } }, new PrivateModule(){ protected void configure() { // スコープが違うので他のモジュールの定義と競合しない。 // 同じことをAbstractModuleでやるとエラー binder().bind( String.class ).toInstance( "var" ); binder().bind( Var.class ); expose( Var.class ); } }); System.out.println( injector.getInstance( Foo.class ).str ); System.out.println( injector.getInstance( Var.class ).str );
実行結果です。
foo var