인프런 커뮤니티 질문&답변

이동진님의 프로필 이미지
이동진

작성한 질문수

자바와 스프링 부트로 생애 최초 서버 만들기, 누구나 쉽게 개발부터 배포까지! [서버 개발 올인원 패키지]

스프링 컨테이너 한 클래스 내에서 두개의 @Repository 사용하기

해결된 질문

작성

·

703

2

BookController 내에서 서로 다른 Repository를 사용하려고 한다면 어떻게 사용해야 하나요?

1번인 saveBook에서는 BookMemoryRepository의 saveBook()을 사용하고

2번인 saveBook1 에서는 BookMySqlRepository의 saveBook()을 사용하고 싶다고 하면 사용할 수 있는지? 사용할 수 있다면 어떻게 사용해야 하나요??

 

 

답변 1

1

최태현님의 프로필 이미지
최태현
지식공유자

안녕하세요, 동진님!! 좋은 질문 감사드립니다! ☺️

크게 2가지 방법이 있을 것 같아요!!!

 

[방법 1. BookRepository 인터페이스 대신 구현체를 2개 주입받는다]

아래 코드와 같은 느낌입니다!!

@RestController
public class BookController {

  private final BookMemoryRepository bookMemoryRepository;
  private final BookMySqlRepository bookMysqlRepository;

  public BookController(
    BookMemoryRepository bookMemoryRepository, 
    BookMySqlRepository bookMysqlRepository
  ) {
    this.bookMemoryRepository = bookMemoryRepository;
    this.bookMysqlRepository = bookMysqlRepository;
  }

  // 사용하고 싶은 곳에 적절한 구현체를 사용한다.
}

이렇게되면 1번에서는 A Repository, 2번에서는 B Repository를 사용하실 수 있게 됩니다!!

또 다른 방법도 있는데요!!

 

[방법 2. BookRepository 인터페이스를 컬렉션으로 주입 받는다]

강의에서 소개드리지는 않았지만, 스프링 빈을 받을 때 List나 Map을 활용할 수도 있습니다!

예를 들어, List 를 사용한다고 해볼게요!

@RestController
public class BookController {

  private final List<BookRepository> bookRepositories;

  public BookController(List<BookRepository> bookRepositories) {
    this.bookRepositories= bookRepositories;
  }

}

이렇게되면 List<BookRepository> bookRepositories 에는 BookMemoryRepositoryBookMySqlRepository 가 모두 들어있게 됩니다!! 그래서 이런 방식으로 구분할 수도 있습니다!!

@Repository
public class BookMemoryRepository {

  @Override
  public RepositoryType getType() {
    return RepositoryType.MEMORY
  }

}

@Repository
public class BookMySqlRepository {

  @Override
  public RepositoryType getType() {
    return RepositoryType.MYSQL
  }

}

// enum class 활용
enum RepositoryType {
  MEMORY,
  MYSQL;
}
@RestController
public class BookController {

  private final List<BookRepository> bookRepositories;

  public BookController(List<BookRepository> bookRepositories) {
    this.bookRepositories= bookRepositories;
  }

  public void method1() {
    // bookRepositories 리스트를 순회하며 getType을 호출하여 MEMORY인 것을 찾는다!
    // stream + filter + findFirst를 쓰셔도 좋고, for문을 도셔도 좋습니다!
  }

  public void method2() {
    // bookRepositories 리스트를 순회하며 getType을 호출하여 MYSQL인 것을 찾는다!
  }

}

만약 Map을 사용하게 되면 key를 String으로, value를 BookRepository로 받으시면 됩니다!!

@RestController
public class BookController {

  private final Map<String, BookRepository> bookRepositories;

  public BookController(Map<String, BookRepository> bookRepositories) {
    this.bookRepositories= bookRepositories;
  }

}

이 경우, 이 Map에는

"bookMemoryRepository" -> BookMemoryRepository 인스턴스
"bookMySqlRepository" -> BookMySqlRepository 인스턴스

가 들어있게 됩니다!!

 

또 혹시나 궁금한 점 있으시면 편하게 질문 남겨주셔요!!!

감사합니다!! 🙏🙏

이동진님의 프로필 이미지
이동진
질문자

친절하고 자세한 답변 감사합니다!! 강의가 귀에쏙쏙들어와서 너무 좋습니다!!

최태현님의 프로필 이미지
최태현
지식공유자

아이고~~ 감사합니다 ㅎㅎㅎ 끝까지 꼭 완주하시기 바래요!!!! 🙏🙇

이동진님의 프로필 이미지
이동진

작성한 질문수

질문하기