복붙노트

[SPRING] @Autowired 생성자 매개 변수를 "required = false"로 개별적으로 설정하는 방법

SPRING

@Autowired 생성자 매개 변수를 "required = false"로 개별적으로 설정하는 방법

@Configuration 클래스 생성자에서 @Autowired 주석을 사용하고 있습니다.

@Configuration
public class MyConfiguration {

   private MyServiceA myServiceA;
   private MyServiceB myServiceB

   @Autowired
   public MyConfiguration(MyServiceA myServiceA, MyServiceB myServiceB){
     this.myServiceA = myServiceA;
     this.myServiceB = myServiceB;    
   }
}

Spring documentation sais로서, 나는 annotated dependency가 필요한지 선언 할 수있다.

@Autowired annotation을 생성자 아래 required = false로 표시하면 autowired 될 두 가지 서비스가 필요하지 않음을 나타냅니다 (Spring documentation sais와 같이).

@Autowired(required = false)
public MyConfiguration(MyServiceA myServiceA, MyServiceB myServiceB){
  this.myServiceA = myServiceA;
  this.myServiceB = myServiceB;   
}

Spring 문서에서 :

각 생성자 매개 변수에 개별적으로 필수 속성을 설정할 수 있습니까? 모든 필드에서 @Autowired 주석을 사용해야합니까?

문안 인사,

해결법

  1. ==============================

    1.Java 8 및 Spring Framework 4를 사용하는 경우 선택 사항을 사용할 수 있습니다.

    Java 8 및 Spring Framework 4를 사용하는 경우 선택 사항을 사용할 수 있습니다.

    @Autowired
    public MyConfiguration(Optional<MyServiceA> myServiceA, Optional<MyServiceB> myServiceB){
      myServiceA.ifPresent(service->{this.myServiceA = service});
      myServiceB.ifPresent(service->{this.myServiceB = service});   
    }
    
  2. ==============================

    2.노골적인 접근

    노골적인 접근

    기본적으로 몇 가지 필수 및 선택 종속성이있는 bean이 있습니다. 이 시나리오를 처리하는 권장 된 방법은 구성 빈뿐만 아니라 다른 구성 요소도 필수 종속성에 대한 생성자를 만들고 선택적 종속에 대한 설정자 주입을 사용하는 것입니다.

    public class MyConfiguration {
    
       private final MyServiceA myServiceA;
       private MyServiceB myServiceB
    
       @Autowired
       public MyConfiguration(MyServiceA myServiceA){
         this.myServiceA = myServiceA;   
       }
    
       @Autowired(required = false)
       public void setMyServiceB(MyServiceB myServiceB) {
         this.myServiceB = myServiceB;
       }
    
    }
    

    이 방법을 사용하면 조롱 라이브러리가 필요없이 클래스를 쉽게 단위 테스트 할 수 있습니다. 생성자 및 선택적인 setter를 사용하여 테스트 상태에서 객체를 만들 수 있습니다.

    필드에 @Autowired (required = false)를 직접 두어 설정자를 제거하는 것도 가능하지만 생성자 삽입을 사용하고 있으므로 종속성을보다 명시 적으로 지정한다고 가정합니다.

    추가 아이디어

    필수 종속성을 줄이기 위해 선택적 형식을 사용할 수도 있습니다. 개발자가 클래스에 속성이 있으면 설정해야한다고 가정하는 것이 일반적입니다. 이는 분명히 시나리오에 맞지 않습니다. 특정 종속성에 대한 부재 가능성을 더 명확하게 표시하려면 선택 사항을 사용할 수 있습니다.

    public class MyConfiguration {
    
       private final MyServiceA myServiceA;
       private Optional<MyServiceB> myServiceB
    
       @Autowired
       public MyConfiguration(MyServiceA myServiceA){
         this.myServiceA = myServiceA;
         this.myServiceB = Optional.empty();   
       }
    
       @Autowired(required = false)
       public void setMyServiceB(MyServiceB myServiceB) {
         this.myServiceB = Optional.ofNullable(myServiceB);
       }
    
    }
    

    어떤 사람들은 (주로 Brian Goetz의 답변으로 인해) 클래스 속성에 Optional 타입을 사용하는 것에 반대합니다. 그러나 결국 팀 전체가 프로젝트에 대해 결정해야합니다.

  3. ==============================

    3.Spring 4.3.0.RC1부터 다음과 같이 할 수 있습니다 :

    Spring 4.3.0.RC1부터 다음과 같이 할 수 있습니다 :

    public MyConfiguration(MyServiceA myServiceA, @Autowired(required = false) MyServiceB myServiceB){
      this.myServiceA = myServiceA;
      this.myServiceB = myServiceB;   
    }
    

    ElementType.PARAMETER가 주석 대상으로 추가되었습니다.

    @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@? MyServiceB?

  4. ==============================

    4.Spring Framework 5.0에서 @Nullable 주석 (예 : JSR-305의 javax.annotation.Nullable과 같은 모든 패키지의 모든 종류)을 사용할 수도 있습니다.

    Spring Framework 5.0에서 @Nullable 주석 (예 : JSR-305의 javax.annotation.Nullable과 같은 모든 패키지의 모든 종류)을 사용할 수도 있습니다.

    @Configuration
    public class MyConfiguration {
    
       private MyServiceA myServiceA;
       private MyServiceB myServiceB
    
       @Autowired
       public MyConfiguration(@Nullable MyServiceA myServiceA, MyServiceB myServiceB){
         this.myServiceA = myServiceA;
         this.myServiceB = myServiceB;    
       }
    }
    
  5. from https://stackoverflow.com/questions/42135102/how-to-set-autowired-constructor-params-as-required-false-individually by cc-by-sa and MIT license