Home Spring MVC
Post
Cancel

Spring MVC

서론

Spring MVC의 모든 내부 구조를 완벽하게 이해하기란 쉽지 않은 일이다. 다만 Spring MVC가 대략 어떻게 동작하는지에 대해서는 학습하는 것이 좋을 것 같아 공부했던 내용들을 간단하게나마 기록해보려고 한다.

Front Controller

Spring MVC의 핵심 동작 원리를 이해하기 전에 우리는 Front Controller 패턴에 대해서 이해할 필요가 있다. 다수의 클라이언트가 어플리케이션 내부에 존재하는 여러 컨트롤러에 요청을 보낸다고 가정해보자.

flowchart LR
    클라이언트1 --> |Call| AController
    클라이언트2 --> |Call| BController
    클라이언트3 --> |Call| CController

A, B, C 컨트롤러는 모두 특정 기능을 수행하는 공통 로직을 담고 있다. 이 공통 로직은 모두 중복 코드이기 때문에, 컨트롤러가 늘어갈 수록 유지 보수에 어려움을 겪을 수 있다. 이때, 클라이언트와 기존 컨트롤러 사이에 Front Controller를 도입하여 중복되는 공통 로직을 처리하고 요청을 이어나갈 수 있도록 설계할 수 있다. 예를 들어, 어떤 요청에는 어떤 컨트롤러를 연결해주어야 하는지 등의 처리를 이 친구가 담당해줄 수 있겠다.

처음 Front Controller에 대한 개념을 들었을 때는 인터셉터랑 큰 차이 없다고 생각했다. 조금 더 찾아보니, Front Controller는 어플리케이션 흐름을 전반적으로 관리하는 중앙 집중식 컨트롤러이고 인터셉터는 중간에 요청/응답을 가로채서 별도의 추가 작업만 수행하는 기능을 하는 점에서 차이가 있었다.

어쨌든, 이 프론트 컨트롤러가 스프링 웹 MVC의 핵심이 된다. 이후에 이 프론트 컨트롤러 패턴을 적용한 것이 DispatcherServlet이다.

DispatcherServlet

DispatcherServlet(디스패처 서블릿)은 HttpServlet을 상속받아 사용된다. 이 친구의 부모 클래스인 FrameworkServletservice() 메서드가 실행되면서 디스패처 서블릿의 다양한 메서드들이 실행된다. 그 중에서 doDispatch() 메서드가 매우 중요하다.

앞서 프론트 컨트롤러로서 할 수 있는 역할이 해당 메서드에 다 들어있다. 요청 URL을 분석하고 핸들러를 조회하거나 어댑터를 조회하는 등의 역할을 모두 수행한다.

flowchart LR
    A(클라이언트) -->|요청| B(서블릿 컨테이너)
    B(서블릿 컨테이너) -->|응답| A(클라이언트)

    B(서블릿 컨테이너) <--> C(Dispatcher Servlet)

    C(Dispatcher Servlet) -->|2. 컨트롤러 호출| D(핸들러 어댑터)
    D(핸들러 어댑터) -->|3. 응답 가공 후 ModelAndView 반환| C(Dispatcher Servlet)

    C(Dispatcher Servlet) <-->|1. 요청 URI에 매핑된 핸들러 탐색| E(핸들러 매핑)

    C(Dispatcher Servlet) <--> F(뷰)

    C(Dispatcher Servlet) <-->|4.뷰를 받아 리턴| G(뷰 리졸버)

    D(핸들러 어댑터) <--> H(컨트롤러)

이 디스패처 서블릿 내부에 여러 메서드들이 모두 실행되면 비로소 이 친구가 수행할 하나의 흐름이 끝이 난다. 그럼 클라이언트의 모든 요청마다 이 흐름이 동일하게 진행되는가? 라는 궁금증이 생길 수 있는데, 이는 상황마다 다를 수 있다. 예를 들어 JSP를 사용하지 않는 REST API의 경우에는 뷰가 필요하지 않아 ModelAndView가 아닌 null을 리턴받기도 하는 것처럼 상황마다 다를 수 있다는 것이다.

This post is licensed under CC BY 4.0 by the author.
Contents

Spring Boot Guide - 4

Spring Boot Guide - 5