스프링을 공부하다 보면 @Component, @Service, @Controller, @Repository를 자주 보게
됩니다.
처음 보면 비슷합니다.
모두 스프링이 관리하는 Bean으로 등록되기 때문입니다.
하지만 이들은 완전히 같은 의미가 아닙니다.
공통점은 Bean 등록이고, 차이점은 역할과 사용 위치입니다.
이번 글에서는 네 어노테이션의 공통점과 차이점, 그리고 왜 구분해서 사용하는지를 간단하고 명확하게
정리해보겠습니다.
공통점
@Component, @Service, @Controller, @Repository는 모두 스프링 빈으로 등록됩니다.
또한 @Service, @Controller, @Repository는 내부적으로 @Component를 기반으로 합니다.
즉, 네 어노테이션의 공통점은 다음과 같습니다.
- 모두 스프링이 관리하는 객체로 등록된다
- 컴포넌트 스캔의 대상이 된다
- @Service, @Controller, @Repository는 @Component의 특수화 형태다
여기까지 보면 비슷해 보일 수 있습니다.
차이는 각 어노테이션이 무슨 역할을 나타내는가에서 생깁니다.
@Component

@Component는 가장 기본적인 빈 등록 어노테이션입니다.
특정 계층을 대표하지 않는 일반적인 스프링 관리 객체에 사용합니다.
예를 들면 다음과 같습니다.
- 공통 유틸 클래스
- 외부 연동 보조 클래스
- 특정 계층으로 분류하기 애매한 일반 컴포넌트
즉, @Component는 범용적인 선택지입니다.
@Service

@Service는 비즈니스 로직을 담당하는 클래스에 사용합니다.
보통 서비스 계층에서 사용하며, 실제 애플리케이션의 핵심 동작이 이곳에 들어갑니다.
예를 들면 다음과 같습니다.
- 회원 가입 처리
- 주문 생성
- 결제 검증
- 정책 판단
@Service의 핵심은 기술적인 기능보다 역할을 명확하게 드러내는 것에 있습니다.
즉, “이 클래스는 비즈니스 로직을 담당한다”는 의미를 표현하는 어노테이션입니다.
@Controller

@Controller는 웹 요청을 처리하는 클래스에 사용합니다.
즉, 프레젠테이션 계층에서 클라이언트의 요청을 받고, 필요한 서비스 로직을 호출한 뒤 응답을 반환하
는 역할을 합니다.
흐름으로 보면 다음과 같습니다.
- 클라이언트가 요청을 보낸다
- 컨트롤러가 요청을 받는다
- 서비스 계층을 호출한다
- 결과를 응답으로 반환한다
@Controller는 단순한 역할 표시로만 끝나지 않습니다.
스프링은 웹 요청 핸들러를 찾을 때 @Controller 계열 어노테이션을 기준으로 사용합니다.
즉, 웹 요청을 처리하는 클래스라면 @Controller 또는 @RestController를 사용하는 것이 맞습니다.
@Repository

@Repository는 데이터 접근을 담당하는 클래스에 사용합니다.
즉, 데이터베이스 조회, 저장, 수정, 삭제 같은 작업을 수행하는 계층에 붙입니다.
예를 들면 다음과 같습니다.
- 데이터 조회
- 저장
- 수정
- 삭제
- 쿼리 실행
@Repository 역시 단순한 역할 표시만 하는 것은 아닙니다.
스프링은 @Repository가 붙은 클래스에서 발생한 예외를 DataAccessException 계층으로 변환
할 수 있도록 지원합니다.
즉, @Repository는 데이터 접근 계층을 나타내는 동시에, 예외 처리 측면에서도 의미가 있는 어노테
이션입니다.
왜 굳이 나눠서 사용할까
이 네 가지는 모두 빈 등록이 가능합니다.
그런데도 나눠서 사용하는 이유는 분명합니다.
첫째, 역할이 더 잘 보이기 때문입니다.
- @Controller를 보면 요청 처리 클래스라는 것을 알 수 있고
- @Service를 보면 비즈니스 로직이라는 것을 알 수 있고
- @Repository를 보면 데이터 접근 계층이라는 것을 알 수 있습니다
둘째, 일부는 스프링의 내부 동작과 연결되기 때문입니다.
- @Controller는 요청 핸들러 식별과 연결되고
- @Repository는 예외 변환과 연결됩니다
즉, 이 어노테이션들은 단순한 이름표가 아니라
역할과 동작을 함께 표현하는 수단입니다.
@Component로 전부 대체해도 될까
결론부터 말하면, 항상 그렇지는 않습니다.
@Controller를 @Component로 대체하는 경우
적절하지 않습니다.
웹 요청을 처리하는 클래스는 @Controller 또는 @RestController로 선언하는 것이 맞습니다.
@Repository를 @Component로 대체하는 경우
빈 등록은 될 수 있습니다.
하지만 예외 변환 기능을 기대하기 어려울 수 있습니다.
@Service를 @Component로 대체하는 경우
기술적으로 큰 문제는 없을 수 있습니다.
하지만 서비스 계층이라는 의미가 흐려집니다.
즉, 가능 여부와 별개로 역할이 명확한 클래스는 전용 어노테이션을 사용하는 편이 좋습니다.
한 번에 정리
어노테이션역할주 사용 위치특징
| @Component | 일반 컴포넌트 | 공통 | 가장 범용적 |
| @Service | 비즈니스 로직 | 서비스 계층 | 역할 표현에 적합 |
| @Controller | 웹 요청 처리 | 프레젠테이션 계층 | 요청 핸들러 식별 |
| @Repository | 데이터 접근 | 데이터 접근 계층 | 예외 변환 지원 |
마무리
@Component, @Service, @Controller, @Repository는 모두 스프링 빈으로 등록된다는 공
통점을 가집니다.
하지만 이들은 같은 어노테이션이 아닙니다.
각 클래스가 어떤 책임을 가지는지 더 분명하게 드러내기 위해 나뉘어 있습니다.
정리하면 이렇게 이해하면 됩니다.
- 웹 요청 처리: @Controller
- 비즈니스 로직: @Service
- 데이터 접근: @Repository
- 그 외 일반 컴포넌트: @Component
다음 포스팅에서는 이번 글에서 계속 등장했던 스프링 빈(Bean) 이 무엇인지, 그리고 스프링이 객체
를 어떻게 생성하고 관리하는지 정리해보겠습니다.
'Programming > Spring' 카테고리의 다른 글
| Flyway 도입으로 정리한 데이터베이스 마이그레이션 관리 (0) | 2026.06.01 |
|---|
