Spring Web MVC

컨테이너·2025년 11월 29일

Spring Boot

목록 보기
1/7
post-thumbnail

1. Spring Web MVC 한 번에 감 잡기

1-1. Spring Web MVC란?

Spring Web MVC는 말 그대로 “웹용 스프링 프레임워크”라고 보면 된다.

  • 클라이언트가 HTTP 요청을 보낸다.
  • 스프링의 Controller가 요청을 받고 비즈니스 로직(Service)을 호출한다.
  • 필요한 데이터는 DAO를 통해 DB에서 가져온다.
  • 가공된 데이터를 Model에 담아서 View(HTML, 템플릿)에 넘긴다.
  • ViewResolver가 어떤 화면을 렌더링할지 결정하고, 최종 응답을 만든다.

핵심 포인트는 두 가지다.

  1. MVC 2 패턴 구조로 웹 애플리케이션을 만든다.
  2. Controller, Service, DAO 같은 객체들의 의존 관계를 스프링 IoC 컨테이너가 관리해 준다.

그래서 개발자는 “객체를 언제 new 해서 연결하지?” 이런 고민보다

“어떤 책임을 어디에 둘까?”에 더 집중할 수 있다.


1-1-1. Spring에서 말하는 MVC 계층

Spring Web MVC에서 이야기를 할 때 보통 이렇게 세 계층으로 나눈다.

  • Controller
  • Service
  • DAO(Repository)

각자 역할을 간단히 보면:

  1. Controller
  • 클라이언트 요청을 받는다.
  • 파라미터를 받고, 검증하고, 필요한 값 가공.
  • Service를 호출해서 비즈니스 로직 실행.
  • 결과 데이터를 Model에 담고, 어떤 View를 보여줄지 결정해서 리턴.
  1. Service
  • “비즈니스 로직”의 중심.
  • 여러 DAO 호출 결과를 조합해서
    • 트랜잭션 처리
    • 로직 분기
    • 계산, 검증 등을 수행한다.
  • Controller에서 받은 입력값을 규칙에 맞게 처리하고, DAO와 통신한 뒤 결과를 반환.
  1. DAO (Data Access Object)
  • DB와 직접 이야기하는 계층.
  • SQL 실행, 데이터 조회/삽입/수정/삭제.
  • JDBC, MyBatis, JPA 등 어떤 기술을 쓰든 “DB 접근 로직”을 여기에 모아둔다.
  • Service는 최대한 “비즈니스 중심 로직”만 남기고, SQL 같은 건 DAO로 빼는 것이 목적.

1-1-2. MVC Architecture가 등장한 이유

초창기(원시적인) 웹 애플리케이션 구조를 떠올려보면 이랬다.

  • 하나의 파일(또는 클래스) 안에서:
    • 화면 출력 HTML
    • 로직 처리 코드
    • DB 조회/수정 SQL 전부 다 섞여 있다.

이 구조의 문제점:

  1. 중복 코드 폭발

    비슷한 기능이 여기저기 흩어져서

    “이 쿼리랑 비슷한 거 저기에도 또 있음…” 이런 상황이 생긴다.

  2. 수정 영향 범위가 너무 넓다

    쿼리 하나, 로직 하나 바꾸려고 해도

    여러 파일을 다 뒤져서 바꿔야 할 수도 있다.

그래서 나온 생각이:

“역할별로 코드를 나누자”

→ 비즈니스 로직 / 화면 / DB 접근을 분리해 관리하자.

이게 바로 MVC 아키텍처의 시작이다.


1-1-3. DAO 계층: DB 접근을 따로 뽑자

먼저 DB 쿼리를 하나의 클래스로 모은 것이 DAO이다.

  • DAO는 “쿼리 단위”로 메서드를 나눈다.
    • insertSomething()
    • selectSomething()
    • updateSomething()
    • deleteSomething()

이렇게 잘게 쪼개두면 장점은:

  • 재사용성이 높다 블록 장난감처럼, 잘게 잘려 있을수록 여러 곳에 갖다 쓰기 쉬운 것처럼, 쿼리도 기능 단위로 쪼개둘수록 여기저기에서 재활용하기 좋다.
  • 유지보수성이 좋다 특정 쿼리가 잘못되었을 때, 그 기능은 DAO 클래스 안에서 고치면 된다. (이 파일 저 파일 다 뒤지지 않아도 된다.)

그리고 또 중요한 개념 하나:

  • 논리적인 “하나의 작업(트랜잭션)”은
    • 하나의 Connection 안에서 처리되어야 한다.
    • 그래서 보통 “Service 쪽에서 Connection을 관리”하고, DAO는 그 Connection을 넘겨받아 쓰는 구조를 취한다.
  • ResultSet은 java.sql에 강하게 의존하므로,
    • 이 의존성을 최대한 DAO 안에 가둬두고
    • Service나 Controller 쪽에는 도메인 객체/DTO로만 넘겨주는 것이 일반적이다.

1-1-4. Service 계층: 비즈니스 로직 + 트랜잭션의 중심

DAO까지 분리했는데도 아직 이런 문제가 남아 있다.

  • 화면(뷰) 코드 안에서 DAO를 직접 부르는 구조라면,
    • 화면이 바뀔 때마다 로직이 같이 엮인다.
    • 같은 로직을 사용하는 다른 화면이 생기면, 또 코드를 복사/붙여넣기 하는 상황이 생긴다.
    • 프론트 개발자와 백엔드 개발자가 같은 파일을 건드려야 해서 충돌도 잦다.

그래서 등장한 것이 Service 계층이다.

Service의 역할은 크게 두 가지다.

  1. 비즈니스 로직 처리
    • 요청 요구사항에 맞는 로직 흐름을 Service에 모은다.
    • 여러 DAO 호출을 조합한다.
    • 값 검증, 도메인 규칙 적용, 상태 변경 등.
  2. 트랜잭션 + Connection 라이프사이클 관리
    • Connection 열기 / 닫기
    • autoCommit(false) 설정 후
      • 중간에 문제 없으면 commit
      • 예외 발생 시 rollback
    • 이런 “하나의 논리적인 작업 단위”를 Service에서 책임진다.

그래서 “Model” 계층 중에서도 실제 핵심은 Service라고 말하기도 한다.

이 철학이 더 확장된 게 바로 “SOA(Service Oriented Architecture, 서비스 지향 아키텍처)” 개념이다.


1-1-5. Controller 계층: View와 Service 사이의 중간 다리

이제 Model(Service/DAO) 쪽은 잘 정리했는데,

여전히 이런 문제가 남아 있다.

  • View에서 Service를 직접 호출하고 있다면:
    • Service 이름이 바뀌거나 메서드 시그니처가 바뀌면 View도 전부 수정해야 한다.
    • Web, Android, iOS 등 “표현 방식(View)”은 다른데 로직(Service)은 같은 경우, 각 View마다 Service 의존 코드가 들어가 있으니 관리가 힘들다.
    • View에 따라 필요한 데이터 가공 방식이 조금씩 달라지는 경우도 있어서, 비즈니스 로직이 오염되기 쉽다.

그래서 나온 해결책이 Controller이다.

Controller의 역할:

  1. 요청 파라미터 수집 + 1차 가공
    • 클라이언트에서 넘겨준 값들(request param, path variable, body 등)을 받는다.
    • 단순 검증 및 타입 변환을 한다.
    • 보안상/논리상 프론트가 넘기면 안 되는 값(예: 서버 시간)은 Controller에서 채운다.
  2. Service 호출
    • 정리된 파라미터를 Service에 전달한다.
    • Service는 비즈니스 로직, DB 접근 등을 모두 처리한다.
  3. 결과 받아서 View로 전달
    • Service가 돌려준 결과를 Model에 담는다.
    • 어떤 View를 렌더링할지 결정한다.
    • JSON 응답, 템플릿, 리다이렉트 등 응답 방식을 고른다.

이렇게 되면 구조가 깔끔해진다.

  • View ↔ Controller
  • Controller ↔ Service
  • Service ↔ DAO

각 계층이 “바로 아래 계층”만 의존하도록 만들어 결합도를 낮춘다.


1-1-6. MVC Architecture 흐름 정리

최종적으로 MVC 구조를 흐름으로 보면:

  1. 사용자가 화면(View)에서 요청을 보낸다.
  2. Controller가 요청을 받고, 파라미터를 처리한다.
  3. Controller는 Service에게 “이 작업 해줘”라고 요청한다.
  4. Service는
    • 필요하면 여러 DAO를 사용해서 DB 작업을 하고
    • 하나의 트랜잭션 단위로 commit/rollback을 관리한다.
  5. Service 결과를 Controller에 반환한다.
  6. Controller는 결과를 Model에 담고 적절한 View를 선택한다.
  7. View는 Model 데이터를 이용해서 화면을 렌더링한다.

이걸 계층 구조로 그리면:

  • View (UI)
  • Controller (요청/응답 조율)
  • Service (비즈니스 로직 + 트랜잭션)
  • DAO/Repository (DB 접근)

스프링 MVC는 이 구조를 프레임워크 수준에서 지원해주는 것이다.

profile
백엔드

0개의 댓글