🌈Programming/Spring
[Spring] 동일 타입의 빈(Bean)이 여러 개일 때 구분하여 주입하기
coco3o
2023. 2. 11. 20:26
반응형
스프링 컨테이너에 빈을 등록하면 스프링 컨테이너가 알아서 의존관계를 맺어준다.
그런데 만약 동일 타입의 빈이 여러 개 존재한다면 (하나의 인터페이스에 여러 개의 구현 클래스가 있다면)
스프링에서 어떻게 구분해서 빈을 주입할까?
예시 코드
public interface JdbcRepository {}
@Repository
public class OracleRepository implements JdbcRepository {}
@Repository
public class MySQLRepository implements JdbcRepository {}
@Service
public class JdbcService {
@Autowired
private JdbcRepository jdbcRepository;
}
동일 타입의 빈이 여러 개일 경우 다음과 같은 방법으로 빈을 구분한다.
- 필드명 매칭
- @Qualifier
- @Primary
1. 필드명 매칭
스프링은 타입으로 빈을 조회하고, 동일 타입 빈이 여러 개일 경우 이름으로 한번 더 빈을 조회한다.
따라서 구체 클래스(OracleRepository) 빈을 주입시키고 싶다면 아래와 같이 필드 명(혹은 파라미터 명)을 빈 이름으로 변경함으로써 해결할 수 있다.
// 필드 주입 예시
@Service
public class JdbcService {
@Autowired
private JdbcRepository oracleRepository;
}
//생성자 주입 예시
@Service
public class JdbcService {
private final JdbcRepository jdbcRepository;
public JdbcService(JdbcRepository oracleRepository) {
this.jdbcRepository = oracleRepository;
}
}
그러나 이 방법은 DIP를 위반하는 방법이므로 사용을 지양하고,
다음에 설명할 @Qualifier와 @Primary 어노테이션을 사용하는 방법으로 해결하자.
2. @Qualifier
@Qualifier는 어떤 빈을 사용할 것인지를 구분할 수 있는 구분자를 붙여주는 방식(빈 이름을 변경하는 것은 아님)이며 다음과 같이 사용한다.
// 필드 주입 예시
@Service
public class JdbcService {
@Qualifier("oracleRepository") // 빈 이름에 맞는 클래스를 찾는다.
@Autowired
private JdbcRepository jdbcRepository;
}
// 생성자 주입 예시
@Service
public class JdbcService {
private final JdbcRepository jdbcRepository;
public JdbcService(@Qualifier("oracleRepository") JdbcRepository jdbcRepository) {
this.jdbcRepository = jdbcRepository;
}
}
3. @Primary
@Primary는 단어의 의미 그대로 우선순위를 정하는 방법이다.
여러 개의 등록된 빈 중 가장 높은 우선순위를 갖는다.
@Primary
@Repository
public class OracleRepository implements JdbcRepository {}
@Service
public class JdbcService {
@Autowired
private JdbcRepository jdbcRepository; // oracleRepository
}
만약 @Primary와 @Qualifier가 동시에 존재한다면 우선순위는 @Qualifier가 가진다.
반응형