@Repository
public class OracleMemberRepositoryImpl implements MemberRepository {
@Override
public void save(Member member) {
...
}
@Override
public Member findById(Long memberId) {
...
}
}
@Repository
public class MysqlMemberRepositoryImpl implements MemberRepository {
@Override
public void save(Member member) {
...
}
@Override
public Member findById(Long memberId) {
...
}
}
@Service
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository; //interface
@Autowired
public MemberServiceImpl(MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
@Override
public void join(Member member) {
...
}
@Override
public Member findMember(Long memberId) {
...
}
}
@SpringBootTest
class CoreApplicationTests {
@Test
void contextLoads() {
}
}
다음과 같은 오류가 발생한다
Spring org.springframework.beans.factory.NoSuchBeanDefinitionException ~~~ expected single matching bean but found 2
무슨뜻일까? 번역해보니 일치하는 빈을 2개 찾았다는 뜻이다. 즉 같은 타입의 빈이 정의 되있을경우 그냥 Autowired로 주입시에는 오류가 발생한다.
방금 Autowired로만 안된다고 했는데 한가지 방법이 있다.
바로 필드 이름이나 파라미터를 구체적인 클래스로 변경하는것이다.
@Service
public class MemberServiceImpl implements MemberService {
/**
* 필드를 변경하거나 파라미터를 변경하거나 둘중에 하나만 구체적인 클래스명으로 변경하면됌.
**/
private final MemberRepository oracleMemberRepositoryImpl;
@Autowired
public MemberServiceImpl(MemberRepository oracleMemberRepositoryImpl) {
this.memberRepository = memberRepository;
}
.
.
.
}
아래와 같이 각 Repository에 Qualifier를 이용해 별칭을 지어준다.
@Repository
@Qualifier("main")
public class OracleMemberRepositoryImpl implements MemberRepository {
.
.
.
}
@Repository
@Qualifier("sub")
public class MysqlMemberRepositoryImpl implements MemberRepository {
.
.
.
}
@Service
public class MemberServiceImpl implements MemberService {
private final MemberRepository memberRepository; //interface
@Autowired
//사용하고자 하는 Repository의 별칭 지정
public MemberServiceImpl(@Qualifier("main")MemberRepository memberRepository) {
this.memberRepository = memberRepository;
}
.
.
.
}
다음과 같이 두개의 Repository 중 사용한 Repository에 @Primary를 붙여놓으면 기본으로 해당클래스가 주입이 된다.(즉 충돌하지않고 Primary가 붙은 빈이 주입됌)
@Repository
@Primary //기본값
public class OracleMemberRepositoryImpl implements MemberRepository {
.
.
.
}
@Qualifier 와 @Primary 가 둘다 있을경우 Qualifier를 우선으로 적용한다.
출처 : 스프링 핵심 원리