지난 포스팅에서 인터페이스 구체화 클래스들의 명시적 사용에 대해서 알아보았다. 만일 이 모든 구현체들을 전부 사용해야 할 때는 어떻게 활용하면 좋을지 이번 포스팅에서 기록해보고자 한다. 결론적으로 Map, List와 같은 1급 컬렉션 클래스 처럼 활용하는 방법이 있다.
@Configuration
public class AutoConfig {
@Bean
public MyRepository jpaRepository() {
return new JpaRepository();
}
@Bean
public MyRepository memoryRepository() {
return new MemoryRepository();
}
}
public interface MyRepository {
...
}
@Repository
public class MemoryRepository implements MyRepository{
...
}
@Repository
public class JpaRepository implements MyRepository{
...
}
Map 자료구조에 key 값으로 빈의 이름, value 값으로 MyRepository 타입의 두 객체를 넣어준다. 구현 클래스가 아닌 추상화된 인터페이스로 Map을 선언하였기 때문에 두 객체를 넣을 수 있다.
class MyServiceTest {
@Test
@DisplayName("2개 이상의 조회 빈을 모두 사용")
void testMultiBeans() {
ApplicationContext ac = new AnnotationConfigApplicationContext(AutoConfig.class, MyService.class);
MyService myService = ac.getBean(MyService.class);
myService.findMyRepository("memoryRepository");
myService.findMyRepository("jpaRepository");
}
static class MyService {
private final Map<String, MyRepository> repositoryMap;
public MyService(Map<String, MyRepository> repositoryMap) {
this.repositoryMap = repositoryMap;
}
public void findMyRepository(String myRepositoryCode) {
System.out.println("MyRepository = " + repositoryMap.get(myRepositoryCode));
}
}
}