Spring에서 @Repository를 쓴다는 것의 의미

Jayson·2025년 4월 8일
0
post-thumbnail

Spring에서 @Repository를 쓴다는 것의 의미

Spring을 사용하다 보면 자주 보게 되는 애노테이션 중 하나가 바로 @Repository입니다.
처음에는 "DB 접근하는 클래스에 붙이는 거지!"라고 단순히 생각하기 쉽지만,
실제로는 훨씬 더 중요한 역할과 의미를 가집니다.

이번 글에서는 @Repository의 진짜 역할부터,
언제 사용하고 언제 생략할 수 있는지,
그리고 DDD(Domain-Driven Design) 스타일 구조에서는 어떻게 사용하는 것이 좋은지까지 함께 살펴보겠습니다.


@Repository는 어떤 역할을 할까?

@Repository는 단순한 마킹용 애노테이션이 아닙니다.
Spring은 이 애노테이션을 통해 아래와 같은 중요한 기능을 제공합니다.

1. 컴포넌트 스캔 대상이 된다

@Repository가 붙은 클래스는 @Component처럼 컴포넌트 스캔 대상이 됩니다.
즉, Spring이 해당 클래스를 자동으로 Bean으로 등록하고,
다른 클래스에서 주입받아 사용할 수 있도록 만들어줍니다.

@Repository
public class MemberJpaRepository { ... }

위 클래스는 애플리케이션 실행 시점에 ApplicationContext에 자동으로 등록되며,
다음과 같이 다른 클래스에서 사용할 수 있습니다:

@RequiredArgsConstructor
@Service
public class MemberService {
    private final MemberRepository memberRepository;
}

2. 예외 변환 기능 제공

가장 큰 차별점이자 @Repository를 쓰는 이유는,
Spring이 데이터 접근 계층에서 발생하는 예외를 일관된 방식으로 처리할 수 있게 도와준다는 점입니다.

  • 예를 들어, JDBC나 JPA에서 발생하는 SQLException 같은 체크 예외(checked exception)를,
  • Spring은 내부적으로 DataAccessException이라는 런타임 예외(runtime exception)로 변환해줍니다.

이 덕분에 우리는 DAO 계층에서 발생하는 예외를 try-catch로 일일이 처리하지 않고도,
상위 계층에서 통일된 방식으로 예외를 다룰 수 있습니다.


그럼 ApplicationContext는 무엇인가?

간단히 말하면,

Spring에서 모든 Bean 객체를 관리하는 중앙 컨테이너입니다.

조금 더 자세히 말하자면:

  • Spring 내부의 IoC(제어의 역전) 컨테이너입니다.
  • @Component, @Service, @Repository, @Controller 등이 붙은 클래스를 스캔하여 Bean으로 등록하고 관리합니다.
  • 의존성 주입(DI)을 통해 객체들 간의 협업을 가능하게 합니다.

즉, @Repository가 붙은 클래스는 이 ApplicationContext에 등록되어 관리되며,
우리가 작성한 대부분의 서비스 클래스와 자연스럽게 협력할 수 있게 됩니다.


@Component vs @Repository

Spring에서는 다음과 같이 여러 계층별로 특화된 애노테이션을 제공합니다:

역할애노테이션
컨트롤러 계층@Controller
서비스 계층@Service
저장소(DAO) 계층@Repository

이들은 모두 내부적으로 @Component를 포함하고 있기 때문에 기능적으로는 Bean 등록이라는 동일한 역할을 수행합니다.
하지만 각 애노테이션은 의도와 책임을 명확히 표현한다는 점에서 의미가 다릅니다.

@Component

  • 가장 일반적인 Bean 등록용 애노테이션입니다.
  • 특별한 계층 구분 없이, 단순히 Spring이 관리하길 원하는 클래스에 붙입니다.
  • 예: 설정 클래스, 유틸 클래스, 외부 API 클라이언트, 커스텀 Validator 등

@Repository

  • @Component의 기능을 포함하면서, 저장소 계층임을 명확히 표현합니다.
  • 예외 변환 기능을 추가로 제공합니다.
  • Spring은 아키텍처 설계 시 계층별 책임을 나누는 것을 권장하며,
    @Repository는 데이터 접근 계층임을 명시적으로 보여줍니다.

DDD 스타일에서의 Repository 사용

도메인 주도 설계(DDD)에서는 Repository를 단순한 DB 접근 클래스가 아니라,
도메인 객체의 컬렉션처럼 취급되는 추상화된 저장소로 봅니다.

Repository의 역할 (DDD 관점)

  • 도메인 객체의 생명 주기를 관리합니다.
  • 복잡한 쿼리 로직은 감추고, 명확한 의도를 가진 메서드 인터페이스를 제공합니다.
  • 구현체는 인프라 계층에 두고, 인터페이스는 도메인 계층에 두는 방식으로 계층 분리를 할 수 있습니다.
// 도메인 계층
public interface MemberRepository {
    Member findById(Long id);
    void save(Member member);
}

// 인프라 계층
@Repository
public class MemberJpaRepository implements MemberRepository {
    // 구현
}

이렇게 하면, 도메인 계층은 JPA든 Mongo든 어떤 구현 기술에도 의존하지 않고 역할에 집중할 수 있습니다.


정리하면

  • @Repository는 단순한 Bean 등록을 넘어서, 예외 변환 및 저장소 계층의 명확한 역할 부여를 위한 애노테이션입니다.
  • Spring은 @Repository가 붙은 클래스에서 발생한 DB 예외를 일관된 런타임 예외로 변환하여 상위 계층에 전달해줍니다.
  • @Component와 기능은 같지만, 개발 의도를 명확히 표현하기 위해 계층별 특화 애노테이션을 쓰는 것이 좋습니다.
  • DDD 관점에서는 Repository를 도메인 모델의 컬렉션처럼 추상화된 저장소로 보고, 역할과 책임 중심으로 구성해야 합니다.
profile
Small Big Cycle

0개의 댓글