2016-08-11 1 views
0

나는 ChildPlugin라는 자식 모듈을하고 난 다음 메인 모듈에서 클래스를 주입 : 그렇지 않은 경우하위 모듈 용 안전 장치 인젝터. 구글 guice의 선택적 바인딩

public class ChildPlugin { 
    private ExampleClass demo; 

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

문제는 내가 메인 모듈이 ExampleClass 결합 여부를 알 수 없다는 것입니다 및 Guice는 인젝터를 만들 때 예외를 throw합니다. 내가하고 싶은 것은 Guice가 ExampleClass가 바인드되어 있지 않은 경우 null 또는 Optional.empty을 전달하는 것입니다. 내가 OptionalBinderExampleClass에 대한 바인더를 변경할 수 있도록

내가 메인 모듈에 액세스 할 수없는, 나는 @NullableChildPlugin.setDemo 방법 Optional<ExampleClass>을 시도했지만 작동하지 않았다.

답변

1

두 가지 방법이 있습니다.

옵션 주입

사용 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();; 
    } 

} 

분사 주석이 지금이 아닌 선택 사항이지만, guice는 클래스 A가 수도를 인식 또는 구속되지 않았을 수 있습니다 :이 코드에서 내가 쓴 같은 그런 다음 옵션 값을 삽입 할 수 있습니다. 그런 다음 그냥 일반적으로 결합 할 수있다, 마지막으로

Object is present: false 
Object is: Optional.empty 

을하고 guice가 주입됩니다 : 실행 코드 조각이 인쇄됩니다

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와의 안전한 선택적인 바인딩을 갖는 방법이다. 나는 이것이 도움이되기를 바란다.

편집 : 방금 guice-3 태그를 보았으므로 선택적 바인더가 아닌 선택적 주석 방법을 사용하고 싶습니다. 선택적 주석을 사용하면 선택적 값이 아닌 null 값을 유지합니다.

아르투르