반응형
Spring Data JPA를 사용할 때, 여러 예제에서 하나의 레포지토리 인터페이스에 Impl 클래스, Custom 인터페이스를 같이 사용하는 것을 볼 수 있다. 왜 이렇게 사용하는 것인지 알아보자.
스프링 레퍼런스를 참고했다. 혹시 내용에 오류가 보인다면 첨언 부탁드립니다.
등장하는 인터페이스와 클래스 목록
interface MyRepository extends JpaRepository, MyRepositoryCustom
interface MyRepositoryCustom
class MyRepositoryImpl implements MyRepositoryCustom
class MyRepositoryCustomImpl implements MyRepositoryCustom
Impl
- Impl은 Spring Data JPA가 인식하는 특별한 네이밍이다. 인터페이스 이름에 Impl 접미사를 가진 구현체를 찾아서 레포지토리 인터페이스와 합치는 기능을 제공한다.
- 그렇다면 MyRepository 인터페이스와 MyRepositoryImpl 클래스에 어떻게 적용되는지 알아보자.위의 코드가 일반적인 클래스와 인터페이스의 관계라면, MyRepository는 func에 대한 구현이 없는 상태다. 심지어 Impl 클래스가 MyRepository 인터페이스를 상속받고 있지도 않다. 그런데 놀랍게도 MyRepository가 func 메소드를 호출하면 "상속 없이도 가능"이라는 값을 리턴한다.
- // MyRepository
interface MyRepository extends JpaRepository
public String func();
// MyRepositoryImpl
class MyRepositoryImpl
public String func() { return "상속 없어도 가능"; } - 어떻게 가능한 것일까? 앞서 말했듯이 인터페이스 이름에 Impl 접미사를 가진 구현체를 찾기 때문에다. 그래서 MyRepositoryImpl 클래스와 MyRepository는 아무런 접점이 없지만 MyRepository로 Impl 클래스의 메소드를 사용할 수 있다.
의문: 그렇다면 레포지토리랑 Impl 구현체만으로 끝나는 거 아닌가? Custom 인터페이스는 왜 필요할까?
Custom
- 기본 레포지토리가 제공하는 Crud 메소드가 아닌, 별도의 사용자 메소드를 정의하기 위한 목적으로 만들어졌다.
- 기본 레포지토리 인터페이스와 사용자 정의 인터페이스를 명시적으로 분리함으로써 확장성을 높일 수 있다.
- 어떻게 사용할 수 있는지 알아보자.MyRepositoryImpl 클래스가 없는 대신, MyRepository는 Custom 인터페이스를 상속받았다. 이 인터페이스의 구현은 CustomImpl 클래스가 한다. 이렇게 선언과 구현을 분리해서 사용한다. 주의해야 할 점은 MyRepository를 상속받지 않았던 MyRepositoryImpl 클래스와 달리, CustomImpl 클래스는 반드시 MyRepositoryCustom 인터페이스를 상속받아야 한다.
- interface MyRepository extends JpaRepository, MyRepositoryCustom
interface MyRepositoryCustom
class MyRepositoryCustomImpl implements MyRepositoryCustom - 왜 이런 차이가 있는 것인지는 추후에 알아보려 한다. 지금은 다른 것들도 정리해야 해서 ㅎㅎ.. 에러 로그를 살펴보니 스프링 데이터가 Fragment implementation을 내부적으로 어떻게 처리하는지 확인하면 알 수 있을 것 같다.
정리
- Impl 네이밍은 반드시 필요하다.
- Custom 네이밍은 굳이 따를 필요 없지만, 관행처럼 굳어진 것이다. 중요한 것은 어떤 인터페이스를 상속했고, 그 인터페이스의 구현 클래스의 이름은 Impl 접미사를 포함해야 한다.
반응형
'Tool > Spring' 카테고리의 다른 글
[Spring boot] JUnit5 테스트 코드 작성하기 (0) | 2023.12.01 |
---|---|
[Spring, DB] @ManyToMany를 지양하는 이유 (2) | 2023.11.24 |
[Spring Security] Spring Security 사용자 인증 정보 접근하기 (0) | 2023.11.21 |
[Spring] Filter 간단 정리 (0) | 2023.11.20 |
[Spring] ApplicationRunner(앱 시작하고 코드 실행하기) 정리 (0) | 2023.10.31 |