복붙노트

[SPRING] Spring @Autowire on Properties 대 생성자

SPRING

Spring @Autowire on Properties 대 생성자

그래서 스프링을 사용하고 있기 때문에 의존성이있는 서비스를 작성한다면 다음과 같이 할 것입니다 :

@Component
public class SomeService {
     @Autowired private SomeOtherService someOtherService;
}

나는 이제 동일한 목표를 달성하기 위해 또 다른 컨벤션을 사용하는 코드를 실행했다.

@Component
public class SomeService {
    private final SomeOtherService someOtherService;

    @Autowired
    public SomeService(SomeOtherService someOtherService){
        this.someOtherService = someOtherService;
    }
}

이 두 가지 방법 모두 작동합니다. 이해합니다. 그러나 옵션 B를 사용하는 것이 몇 가지 이점이 있습니까? 나에게 클래스 및 단위 테스트에서 더 많은 코드를 생성합니다. (생성자를 작성하고 @InjectMocks를 사용할 수 없음)

내가 누락 된 것이 있습니까? 단위 테스트에 코드를 추가하는 것 외에 autowired 생성자가 수행하는 작업이 있습니까? 의존성 주입을하는 것이 더 바람직한 방법입니까?

해결법

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

    1.예, 옵션 B (생성자 삽입이라고 함)는 실제로 필드 주입보다 권장되며 몇 가지 장점이 있습니다.

    예, 옵션 B (생성자 삽입이라고 함)는 실제로 필드 주입보다 권장되며 몇 가지 장점이 있습니다.

    봄 기고 가인 Olivier Gierke가 작성한 자세한 기사는이 블로그 게시물을 참조하십시오.

  2. ==============================

    2.간단히 설명 드리겠습니다.

    간단히 설명 드리겠습니다.

    옵션 (A)에서는 Spring Container 내부 / 외부의 다른 클래스에있는 모든 사람이 기본 생성자 (예 : new SomeService ())를 사용하여 인스턴스를 만들 수 있도록 허용합니다. SomeOtherService 객체 (종속성) 당신의 SomeService.

    Option (B)는 SomeOtherService 의존성을 실제로 해결하지 않고 SomeService 객체를 생성하는 것을 허용하지 않기 때문에 선호되는 접근법이다.

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

    3.Autowired 생성자는 스프링 컨테이너에 등록하기 전에 사용자 정의 코드를 추가하기위한 후크를 제공합니다. SomeService 클래스가 SuperSomeService라는 또 다른 클래스를 확장한다고 가정하고, 이름을 인수로 취하는 생성자를가집니다. 이 경우 Autowired 생성자가 올바르게 작동합니다. 또한 초기화 할 다른 멤버가있는 경우 인스턴스를 스프링 컨테이너로 반환하기 전에 생성자에서 인스턴스를 초기화 할 수 있습니다.

    Autowired 생성자는 스프링 컨테이너에 등록하기 전에 사용자 정의 코드를 추가하기위한 후크를 제공합니다. SomeService 클래스가 SuperSomeService라는 또 다른 클래스를 확장한다고 가정하고, 이름을 인수로 취하는 생성자를가집니다. 이 경우 Autowired 생성자가 올바르게 작동합니다. 또한 초기화 할 다른 멤버가있는 경우 인스턴스를 스프링 컨테이너로 반환하기 전에 생성자에서 인스턴스를 초기화 할 수 있습니다.

    public class SuperSomeService {
         private String name;
         public SuperSomeService(String name) {
             this.name = name;
         }
    }
    
    @Component
    public class SomeService extends SuperSomeService {
        private final SomeOtherService someOtherService;
        private Map<String, String> props = null;
    
        @Autowired
        public SomeService(SomeOtherService someOtherService){
            SuperSomeService("SomeService")
            this.someOtherService = someOtherService;
            props = loadMap();
        }
    }
    
  4. from https://stackoverflow.com/questions/40620000/spring-autowire-on-properties-vs-constructor by cc-by-sa and MIT license