Spring Boot DI 빈 탐색 전략

DongHwan·2022년 3월 13일
0

Spring & Spring Boot

목록 보기
5/5

스프링에서 의존성 주입을 할 때 같은 타입의 빈이 여러개 있는 경우, 어떤 빈을 선택할지 지정을 해주어야 한다. 지정을 해주는 방법에는 대표적으로 3가지가 있는데, 이에 대해 정리해보고자 한다.

Autowired 필드명 매칭

의존성 주입을 할 때, 타입을 먼저 매칭한다. 만약 같은 타입의 빈이 여러개 있는 경우 빈의 이름으로 매칭을 수행한다. 빈의 이름으로 매칭을 할 때는 의존성이 주입될 필드명 혹은 파라미터명과 비교한다.

// 각각 example1과 example2를 이름으로 가지는 Example 타입의 빈이 있다.

@Component
public class ExClass {
  private final Example example;

  @Autowired
  public ExClass(Example example) {
    this.example = example;
  }
}

위 예시에서 Example 타입의 빈의 의존성을 주입받는다. 우선 타입으로 매칭을 시도하는데, 위 예시에서는 Example 타입의 빈이 2개이다. 그러니 이후 빈의 이름으로 매칭을 시도하는데, 이경우 매칭되는 이름이 없으므로 결국 에러가 발생한다.

// 각각 example1과 example2를 이름으로 가지는 Example 타입의 빈이 있다.

@Component
public class ExClass {
  private final Example example;

  @Autowired
  public ExClass(Example example1) {
    this.example = example1;
  }
}

그러나 위 예시처럼 의존성 주입이 일어나는 메서드의 파라미터 명을 빈의 이름과 같게 해주면, 정상적으로 동작한다.

빈의 이름으로 매칭하는 방법은 빈의 이름이 의도치않게 변경될 가능성이 있으며, 매칭된 정보를 추적하기도 굉장히 어렵다. 그러니 사용하는 것을 지양하는 것이 좋다.

Qualifier

두번째 방법은 @Qualifier 어노테이션으로 매칭을 위한 추가적인 구분자를 제공하는 것이다. 위에서 빈의 이름으로 매칭한 것과는 달리, Qualifier는 매칭을 위한 추가적인 이름을 정의하고 이를 사용하여 매칭하는 것이다.

@Component
@Qualifier("exampleBean1")
public class Example1 implements Example {}

@Component
@Qualifier("exampleBean2")
public class Example2 implements Example {}

위 예시에서 두 빈의 이름은 각각 example1example2이다. 그리고 @Qualifier를 통해 추가적인 구분자를 지정해주었으며, 각각 exampleBean1exampleBean2이다.

@Component
public class ExClass {
  private final Example example;

  @Autowired
  public ExClass(@Qualifier("exampleBean1") Example example) {
    this.example = example;
  }
}

이렇게 추가적인 구분자를 지정해주었다면, 이후 의존성 주입이 이루어지는 곳에서 해당 구분자를 사용하여 원하는 빈을 가져올 수 있다.

Primary

마지막으로 @Primary 어노테이션을 사용하여, 특정 빈에게 우선권을 줄 수 있다.

@Component
@Primary
public class Example1 implements Example {}

@Component
public class Example2 implements Example {}

위 예시에서 Example1 클래스에 @Primary 어노테이션을 붙여주었다. 그러면 해당 클래스의 빈은 다른 빈들보다 우선권을 가지게 되어 먼저 선택된다.

@Component
public class ExClass {
  private final Example example;

  @Autowired
  public ExClass(Example example) {
    this.example = example;
  }
}

위처럼 의존성 주입을 받는 곳에서는 추가적인 작업을 하지 않아도, 우선권이 있는 example1 빈이 주입이 되게 된다.

Qualifier vs Primary

앞에서 말했듯이 필드명을 통해 빈을 선택하는 방법은 지양하는 것이 좋다. 그렇다면 Qualifier와 Primary 두가지를 주로 쓰게될 것인데, 어떤 상황에 어떤 것을 사용하는 것이 좋을까?

사실 두가지를 같이 섞어쓰는 것이 개발하는데 있어 생산성을 높일 수 있다. Qualifier는 명시적으로 상세하게 빈을 선택할 수 있다. 단, 이를 위해 의존성 주입이 일어나는 곳마다 @Qualifier를 사용해주어야 한다. 반대로 Primary는 기본값의 개념으로 한번 지정해두면, 다른 코드에서는 추가적인 작업이 필요가 없다.

이런 특징을 살려서, 자주 사용되는 빈을 Primary로 등록하고 종종 사용되는 빈에는 Qualifier를 등록해주면 좋다. 자주 사용하는 빈을 쓸 때는 별다른 설정없이 편하게 사용을 하면 되고, 특정한 상황에서는 Qualifier를 사용해서 명시적으로 해당 빈을 꺼내쓰는 것이다. 이런 방식으로 코드를 작성하면, 코드를 깔끔하고 생산성 좋게 작성할 수 있다.

profile
날 어떻게 한줄로 소개해~

0개의 댓글