2016-08-11 64 views
0

我有一個名爲ChildPlugin孩子模塊和I注入從主模塊類如下:子模塊的失效安全注射器。在谷歌吉斯可選綁定

public class ChildPlugin { 
    private ExampleClass demo; 

    @Inject 
    public void setDemo(ExampleClass demo) { 
     this.demo = demo; 
    } 
} 

的問題是,我不知道主模塊是否與ExampleClass,如果它不Guice創建注入器時引發異常。我想要做的就是讓吉斯通nullOptional.empty如果ExampleClass中未綁定。

我沒有進入主模塊,所以我不能爲ExampleClass改變粘結劑OptionalBinder,我試圖@NullableChildPlugin.setDemo方法Optional<ExampleClass>,但沒有奏效。

回答

1

有2種方式來做到這一點。

可選注入

使用com.google.inject.Inject註解。這一個允許你在註釋中指定可選項。看到這個例子:

public class GuiceInjectOptional extends AbstractModule { 

    @Override 
    protected void configure() { 

     // method 1: 
     bind(B.class).in(Singleton.class); 

    } 

    public static class A { 

     private String name; 
     // non null constructor so that A can't be instantiated automatically by guice 
     public A(String name) { 
      this.name = name; 
     } 

     @Override 
     public String toString() { 
      return "I am: " + name; 
     } 
    } 

    public static class B { 

     @Inject(optional=true) 
     A obj; 

     void run() { 
      System.out.println("Object is: " + obj); 
     } 
    } 

    public static void main(String[] args) { 
     Injector injector = Guice.createInjector(new GuiceInjectOptional()); 
     injector.getInstance(B.class).run();; 
    } 

} 

B類的註釋表明A是可選的。它沒有被注入。運行代碼片段打印:

Object is: null 

方法2(這是你在guice 4+後執行的方式)。您可以指定可選的綁定。這些綁定甚至可以讓你定義默認值,如果你喜歡。然後,您可以注入一個可選值就像在這個片段中,我寫了起來:

public class GuiceInjectOptional extends AbstractModule { 

    @Override 
    protected void configure() { 
     // set up optional binding for A. 
     OptionalBinder.newOptionalBinder(binder(), A.class); 

     bind(B.class).in(Singleton.class); 
    } 

    public static class A { 

     private String name; 
     // non null constructor so that A can't be instantiated automatically by guice 
     public A(String name) { 
      this.name = name; 
     } 

     @Override 
     public String toString() { 
      return "I am: " + name; 
     } 
    } 

    public static class B { 

     @Inject 
     Optional<A> obj; 

     void run() { 
      System.out.println("Object is present: " + obj.isPresent()); 
      System.out.println("Object is: " + obj); 
     } 
    } 

    public static void main(String[] args) { 
     Injector injector = Guice.createInjector(new GuiceInjectOptional()); 
     injector.getInstance(B.class).run();; 
    } 

} 

在注入註解是現在非可選,但吉斯知道,A類可能會或可能不會被束縛。 運行代碼將打印:

Object is present: false 
Object is: Optional.empty 

最後,那麼你可以綁定一個正常和吉斯將其注入:

public class GuiceInjectOptional extends AbstractModule { 

    @Override 
    protected void configure() { 
     // set up optional binding for A. 
     OptionalBinder.newOptionalBinder(binder(), A.class); 

     bind(A.class).toInstance(new A("Pandaa!")); 
     bind(B.class).in(Singleton.class); 
    } 

    public static class A { 

     private String name; 
     // non null constructor so that A can't be instantiated automatically by guice 
     public A(String name) { 
      this.name = name; 
     } 

     @Override 
     public String toString() { 
      return "I am: " + name; 
     } 
    } 

    public static class B { 

     @Inject 
     Optional<A> obj; 

     void run() { 
      System.out.println("Object is present: " + obj.isPresent()); 
      System.out.println("Object is: " + obj); 
     } 
    } 

    public static void main(String[] args) { 
     Injector injector = Guice.createInjector(new GuiceInjectOptional()); 
     injector.getInstance(B.class).run();; 
    } 

} 

而且上面會打印:

Object is present: true 
Object is: Optional[I am: Pandaa!] 

而且這是你如何失敗安全與guice可選綁定:)我希望這可以幫助。

編輯:我剛纔看到的吉斯-3標籤,所以你要使用可選的標註方法,而不是可選的粘合劑。使用可選註釋時,它將保持爲空而不是可選值。

Artur