개발_기초 정보

[spring] 스프링 빈 조회 할 때 빈이 2개 여러 개 일 경우

메타듀 2023. 2. 21. 11:11
728x90
반응형

Spring Bean Test

interface

public interface Chef {
    String cook();
}

Java

@Repository  // <- annotation
public class KoreanChef implements Chef{
    @Override
    public String cook() {
        return "한우육회덮밥";
    }

}
@ToString
@Service
@RequiredArgsConstructor
public class Restaurant {
    (1번)
    //필드 주입
    @Autowired  //chef 타입의 객체를 주입
    private Chef chef;

    (2번)
    //주입이 필요하면 final 선언
    //생성자 주입 , 자동 주입
    private final Chef chef;
}

@Autowired를 통해 주입하거나
final 이용하여 자동 주입한다.

제대로 작동하는 지 테스트를 해보자!

@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations="file:src/main/webapp/WEB-INF/root-context.xml")
@Log4j2
public class ChefTests {

    @Setter(onMethod_ = { @Autowired })
    private Restaurant restaurant;

    @Test
    public void testExist() {
        assertNotNull(restaurant);

        log.info(restaurant);
        log.info("----------------------------------");
        log.info(restaurant.getChef());
    }

}

테스트 성공!!!

만약, @Autowired를 통한 자동 의존관계 주입시 여러개의 빈을 찾는다면?
빈을 하나 더 생성하고 테스트를 실행해보자!

Japan을 하나 추가!!!

@Repository
public class JapanChef implements Chef {

    @Override
    public String cook() {
        return "참치초밥";
    }

}

다시 테스트를 실행..

오류 발생!
expected single matching bean but found 2: japanChef,koreanChef
스프링이 빈을 두개 찾아서 어떤 것을 매칭할 지 모르겠다는 뜻 같다.

찾은 여러개의 빈(Bean)들 중 어떤 것을 할 지 기준이 없다.
스프링은 하나라도 에러가 있으면 아예 뜨지 않는다!

여러개의 빈을 찾을 때 해결할 수 있는 2가지 방법

1) @Primary
2) @Qualifier

1) @Primary

자바 빈에서 @Primary를 붙이면 우선 순위가 부여 된다! 여러개의 빈에서 원하는 빈에 붙여 나올 수 있게 한다.
실무에서 많이 사용하는 방법이라고 한다!

import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Repository;

@Primary
@Repository
public class KoreanChef implements Chef{

    @Override
    public String cook() {
        return "한우육회덮밥";
    }
}

나는 koreanChef 에 @Primary를 붙여줌!


테스트 성공!

2) @Qualifier

각각의 빈의 @Qulifier("클래스 이름")을 붙여준다.

그런 후, Restaurant클래스에

    @Qualifier("JapanChef")
    @Autowired
    private Chef chef;

선택한 빈의 클래스 이름을 붙인다.


테스트 성공!

반응형