[Spring] Dependency Injection

myminimin·2023년 8월 23일
0

Spring/Springboot

목록 보기
5/21
post-thumbnail
post-custom-banner

Dependency Injection

1. Constructor Injection(생성자 주입)

  • Spring에서 권장하는 방식. 4.3 버전부터는 단일 생성자인 경우에 @Autowired 안붙여도 자동으로 주입이 된다. (생성자가 2개 이상인 경우에는 어노테이션을 붙여야 한다)
 @Component
public class MadExample {

    // final로 선언할 수 있는 보너스
    private final HelloService helloService;

    // 단일 생성자인 경우는 추가적인 어노테이션이 필요 없다.
    public MadExample(HelloService helloService) {
        this.helloService = helloService;
    }
}

2. Field Injection(필드 주입)

  • 사용법이 매우 간단. 필드에 @Autowired을 붙여주면 자동으로 의존성이 주입이 된다. 예제 코드를 만들 때 자주 사용한다.
 @Component
public class MadExample {

    @Autowired
    private HelloService helloService;
}

3. Setter Injection(수정자 주입)

  • 꼭 setter 메서드일 필요는 없다. 메서드 이름이 수정자 네이밍 패턴(setXXXX)이 아니어도 동일한 기능을 하면 된다. 그래도 일관성과 명확한 코드를 만들기 위해서 정확한 이름을 사용하는 것을 추천한다.
 @Component
public class MadExample {

    private HelloService helloService;

    @Autowired
    public void setHelloService(HelloService helloService) {
        this.helloService = helloService;
    }
}

Spring에서는 1. 생성자 주입 방법을 더 권장하는 이유가 뭘까?

  • 순환 참조를 방지할 수 있다.
    : 필드 주입이나 수정자 주입 방법으로 개발을 하면 A가 B를 참조하고, B가 다시 A를 참조하는 순환 참조가 발생 할 수도 있는데 (빈이 생성된 후에 비즈니스 로직으로 인하여 서로의 메소드를 순환 참조하는 형태)
    이런 상황에 실행을 하면 아무런 오류 없이 정상적으로 구동이 된다는 것이 문제이다. 실제 코드가 호출되기 전까지 문제를 발견할 수 없다.
    -> 하지만 생성자 주입 방법을 사용하면 BeanCurrentlyInCreationException이 발생하며 애플리케이션이 구동조차 되지 않는다. 따라서 발생할 수 있는 오류를 사전에 알 수 있다.

실행 결과에 차이가 발생하는 이유가 뭘까?

  • 생성자 주입 방법은 필드 주입이나 수정자 주입과는 빈을 주입하는 순서가 다르다.
  1. Setter Injection(수정자 주입)은 우선 주입 받으려는 빈의 생성자를 호출하여 빈을 찾거나 빈 팩터리에 등록한다. 그 후에 생성자 인자에 사용하는 빈을 찾거나 만든다. 그리고 주입하려는 빈 객체의 수정자를 호출하여 주입한다.

  2. Field Injection(필드 주입)은 수정자 주입 방법과 동일하게 먼저 빈을 생성한 후에 어노테이션이 붙은 필드에 해당하는 빈을 찾아서 주입하는 방법이다.

  3. 마지막으로 Constructor Injection(생성자 주입)은 생성자로 객체를 생성하는 시점에 필요한 빈을 주입한다. -> 먼저 빈을 생성하지 않는다.

    그렇기 때문에 순환 참조는 생성자 주입에서만 문제가 된다. 객체 생성 시점에 빈을 주입하기 때문에 서로 참조하는 객체가 생성되지 않은 상태에서 그 빈을 참조하기 때문에 오류가 발생한다.

    그렇다면 순환 참조 오류를 피하기 위해서 수정자 또는 필드 주입을 사용해야 할까? 오히려 그렇지 않다. 순환 참조가 있는 객체 설계는 잘못된 설계이기 때문에 오히려 생성자 주입을 사용하여 순환 참조되는 설계를 사전에 막아야 한다.


  • 테스트 코드 작성이 편리하다
  • 조금 더 품질 좋은 코드를 만들 수 있다
  • 실핼 중에 객체가 변하는 것을 막을 수 있다
  • 오류를 사전에 방지할 수 있다

https://madplay.github.io/post/why-constructor-injection-is-better-than-field-injection

post-custom-banner

0개의 댓글