[Spring] 3. 계층형 아키텍처
만약 모든 코드를 하나의 클래스에 작성한다면 어떻게 될까?
코드는 금세 스파게티처럼 얽히고, 작은 기능 하나를 수정하는 것도 어려워질 것이다.
좋은 소프트웨어는 각 객체가 자신만의 역할과 책임을 명확히 아는 것에서부터 시작한다. 웹 애플리케이션의 가장 기본 구조인 계층형 아키텍처(Layered Architecture)와 각 계층의 역할에 대해 정리해보자.
스프링의 3대 핵심 계층
스프링 웹 애플리케이션은 보통 크게 3개의 계층으로 역할을 나눈다.
이를 통해 각 계층은 자신의 책임에만 집중할 수 있어 코드의 유지보수성과 재사용성을 극대화할 수 있다.
이는 SOLID 원칙 중 SRP(단일 책임 원칙)를 충실히 따르는 설계 방식이기도 하다.
1. Controller - 표현 계층 (Presentation Layer)
- 어노테이션:
@Controller
,@RestController
Controller
는 클라이언트의 HTTP 요청을 직접적으로 처리하는 애플리케이션의 관문이다.
부 세계와 애플리케이션 내부 로직을 연결하는 다리 역할을 한다.
주요 책임
- URL 매핑, HTTP 메서드(GET, POST 등)를 통해 들어온 요청을 수신한다.
- 요청에 포함된 데이터(파라미터, JSON 등)를 적절한 자바 객체로 변환한다.
- 요청에 대한 처리를
Service
계층에 위임한다. Service
의 처리 결과를 받아, 사용자에게 반환할 응답(HTML 뷰 이름, JSON 데이터 등)을 구성한다.
Controller
는 HTTP 프로토콜과 관련된 일을 처리한다
Controller
가 애플리케이션의 핵심 비즈니스 로직을 포함해서는 안 된다.
2. Service - 서비스 계층 (Service Layer)
- 어노테이션:
@Service
Service
는 애플리케이션의 핵심 비즈니스 로직을 구현하고 처리하는 중심부다.
사용자의 요구사항을 실제로 해결하는 구체적인 작업들이 이 계층에서 이루어진다.
주요 책임:
Controller
로부터 전달받은 데이터를 바탕으로 비즈니스 규칙에 맞는 처리를 수행한다.- 하나의 비즈니스 로직을 위해 여러
Repository
를 호출하여 데이터 작업을 조율한다. - 트랜잭션 관리와 같은 데이터의 일관성 및 무결성을 보장하는 역할을 수행한다.
Service
계층은 HTTP와 같은 외부 기술이나 데이터베이스와 같은 데이터 영속성 기술에 직접적으로 의존하지 않고, 순수하게 비즈니스 로직에만 집중해야 한다.
3. Repository - 데이터 접근 계층 (Data Access Layer)
- 어노테이션:
@Repository
Repository
는 데이터베이스와 같은 영속성 계층(Persistence Layer)에 대한 접근을 전담한다.
모든 데이터 관련 작업은 이 계층을 통해서만 이루어진다.
주요 책임:
- 데이터베이스에 대한 CRUD(Create, Read, Update, Delete) 작업을 수행한다.
Service
계층이 비즈니스 로직에 집중할 수 있도록 데이터베이스와의 통신과 관련된 복잡한 구현을 숨긴다.- 데이터베이스에서 발생하는 예외를 스프링의 일관된 예외로 변환하여
Service
계층에 전달한다. - ex)
SQLException
->DataAccessException
Repository
는 어떤 비즈니스 로직에서 자신을 호출하는지 알 필요 없이, 오직 데이터의 저장, 조회, 수정, 삭제라는 책임에만 집중한다.
요청 처리 흐름 정리
이 세 계층은 다음과 같은 흐름으로 협력하며 사용자의 요청을 처리한다.
사용자(Client)가 HTTP 요청을 보낸다.
Controller
가 요청을 받아 파라미터를 확인하고,Service
에 로직 처리를 위임한다.Service
는 비즈니스 로직을 수행하며, 데이터 처리가 필요하면Repository
에 요청한다.Repository
는 데이터베이스에서 데이터를 조회하거나 변경한다.처리된 데이터는 역순(
Repository
→Service
→Controller
)으로 전달된다.Controller
는 최종 결과를 사용자에게 HTTP 응답으로 반환한다.