[Spring] 여러 개의 빈(Bean)이 같은 타입을 가질 경우, 의존성을 주입하는 방법

gogori6565·2024년 7월 12일
0

스프링 부트 공부

목록 보기
7/20
post-thumbnail

스프링 컨테이너에 빈을 등록하면 의존관계는 스프링 컨테이너가 알아서 맺어준다.

그런데 만약 동일 타입의 빈이 여러 개라면 스프링이 어떻게 구분을 해서 알맞은 빈을 주입할까?


문제 제기

public class SomeClass {

    private final SomeInterface someBean;

    @Autowired
    public SomeClass(SomeInterface someBean) {
        this.someBean = someBean;
    }

    // 사용할 메서드 등
}

위와 같은 의존성 주입 코드가 있다.

Spring은 IoC 컨테이너에서 SomeInterface를 구현한 어떤 클래스의 인스턴스를 찾아서 빈을 검색하고 주입한다.

만약 여기서 SomeInterface로 구현한 클래스가 2개 이상이라면 어떤 클래스의 인스턴스를 주입할까? (= 동일 타입의 빈이 여러 개라면)

1. @Primary 사용

@Primary 어노테이션을 사용하면 특정 빈을 기본 빈으로 지정할 수 있다. @Primary가 붙은 빈이 여러 개의 등록된 빈 중 가장 높은 우선순위를 가진다.

@Component
@Primary
public class PrimaryBean implements SomeInterface {
    // Implementation
}

2. @Qualifier 사용

@Qualifier 어노테이션을 사용하면 명시적으로 어떤 빈을 주입할지 지정할 수 있다.

@Component
@Qualifier("qualifier1")
public class QualifiedBean1 implements SomeInterface {
    // Implementation
}

@Component
@Qualifier("qualifier2")
public class QualifiedBean2 implements SomeInterface {
    // Implementation
}
public class SomeClass {

    private final SomeInterface bean;

    @Autowired
    @Qualifier("qualifier1") // qualifier1을 사용하겠다고 지정
    public SomeClass(SomeInterface bean) {
        this.bean = bean;
    }

    // 사용할 메서드 등
}

👉 만약 @Primary@Qualifier가 동시에 존재하면 우선순위는 @Qualifier에게 간다!!

3. 구체적인 빈의 이름 지정

빈의 이름을 직접 지정해 어떤 빈을 주입할지 명시적으로 지정한다.

@Component("specificBeanName")
public class SpecificBean implements SomeInterface {
    // Implementation
}
public class SomeClass {

    private final SomeInterface bean;

    @Autowired
    public SomeClass(@Qualifier("specificBeanName") SomeInterface bean) {
        this.bean = bean;
    }

    // 사용할 메서드 등
}
  • @Component : Spring의 컴포넌트 스캔 기능을 통해 스프링 컨테이너가 해당 클래스를 자동으로 빈(Bean)으로 등록하게 만드는 것
  • @Component("specificBeanName")와 같이 이름을 명시하면, 해당 빈의 이름을 specificBeanName으로 설정한다.

➕ 위의 규칙들이 없으면 Spring은 다음과 같은 기본 규칙을 따른다.

  • @Primary가 지정되지 않은 경우, 가장 최근에 등록된 빈이 주입될 수 있다.
  • 만약에도 결정이 불가하다면, Spring은 NoUniqueBeanDefinitionException 예외를 던진다.
profile
p(´∇`)q

0개의 댓글