MVC

[MVC] Spring MVC와 Dispatcher Servlet

쌈뽕코딩 2025. 2. 13. 20:56

목차

  • Spring MVC
    • MVC란 무엇인가?
    • MVC의 등장 배경
  • DispatcherServlet
    • 역할
    • 동작과정

Spring MVC

Spring MVC(Model-View-Controller)는 Spring Framework의 핵심 모듈 중 하나로, 웹 애플리케이션 개발을 위한 디자인 패턴인 MVC 패턴을 구현한 것이다. 이 패턴은 애플리케이션의 로직을 세 가지 주요 구성 요소로 분리하여 관리한다. Spring MVC는 웹 애플리케이션을 구조화하고, 테스트와 유지보수를 용이하게 만들기 위해 설계되었다.

  1. Model: 애플리케이션의 핵심 데이터와 비즈니스 로직을 나타낸다. 보통 도메인 객체나 데이터베이스와 상호작용하는 객체들이다.
  2. View: 사용자에게 보여지는 화면을 담당한다. 일반적으로 JSP, Thymeleaf, FreeMarker 등의 템플릿 엔진을 사용하여 구현한다.
  3. Controller: 사용자의 요청을 받고 이를 처리한 후, 적절한 뷰를 반환하는 역할을 한다. 요청을 처리하는 로직을 담당하며, 비즈니스 로직을 실행하는 서비스 계층과 협력한다.

이렇게 Spring MVC는 DispatcherServlet을 중심으로 요청을 처리하며, 각 컴포넌트가 책임을 분담하여 애플리케이션을 효율적으로 관리할 수 있게 돕고 있다.

 

👟 Spring MVC의 등장 배경

Spring MVC는 웹 애플리케이션 개발에서의 복잡성과 관리의 어려움을 해결하기 위해 등장했다.

이전에는 JSP와 서블릿을 사용하여 웹 애플리케이션을 구축했지만, 비즈니스 로직과 UI 로직의 분리가 부족하여 코드가 복잡하고 유지보수가 어려웠다. 이 문제를 해결하기 위해 MVC 패턴이 도입되었다. 아래는 비즈니스 로직과 UI 로직의 분리가 부족한 예시이다.

@WebServlet("/product")
public class ProductServlet extends HttpServlet {
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 비즈니스 로직: 상품 데이터 처리
        String productId = request.getParameter("productId");
        
        // 직접 비즈니스 로직을 서블릿 내에서 처리 (상품 정보 조회)
        Product product = getProductFromDatabase(productId);
        
        // UI 로직: 상품 정보를 JSP에 전달
        request.setAttribute("product", product);
        
        // JSP로 이동
        request.getRequestDispatcher("/product.jsp").forward(request, response);
    }
    
    private Product getProductFromDatabase(String productId) {
        // 예시: DB에서 상품 정보 가져오는 코드 (가정)
        return new Product(productId, "Example Product", 100.0);
    }
}
  • 비즈니스 로직과 UI 로직의 결합: JSP나 서블릿 내에서 비즈니스 로직을 처리하면, 코드가 서로 얽히고 복잡해져 유지보수가 어려워진다.
  • 테스트의 어려움: UI와 비즈니스 로직이 결합되면 단위 테스트가 어려워진다.
  • 재사용성 부족: UI와 비즈니스 로직이 섞여 있어 재사용성이 낮다.

Spring MVC는 이러한 문제를 해결하기 위해 비즈니스 로직과 프레젠테이션 로직을 분리하고, 모든 컴포넌트를 명확히 분리하여 관리할 수 있게 돕는다. 또한, 테스트 가능한 아키텍처를 제공하고, 유연한 설정과 확장성을 제공한다. Spring MVC는 스프링의 종합적인 웹 애플리케이션 솔루션을 제공하며, IoC(제어의 역전) AOP(관점 지향 프로그래밍) 기능을 통해 애플리케이션을 더 유연하고 효율적으로 만들 수 있도록 지원하고 있다.


DispatcherServlet

DispatcherServlet은 Spring MVC에서 프론트 컨트롤러 역할을 한다. 모든 HTTP 요청은 DispatcherServlet을 통해 들어오며, 이를 기반으로 다양한 핸들러 매핑, 뷰 리졸버, 예외 처리 등을 설정하여 요청을 처리한다.

 

1️⃣ DispatcherServlet의 주요 역할

  1. 요청과 컨트롤러 간의 연결
    • DispatcherServlet은 요청을 어떤 컨트롤러가 처리할지 HandlerMapping을 통해 찾는다.
    • 그러나 DispatcherServlet이 바로 컨트롤러를 실행하지 않고, 핸들러 어댑터를 통해 요청을 처리하게 합니다.
    • 핸들러 어댑터는 다양한 컨트롤러 타입을 처리할 수 있도록 설계되어 있으며, 각 컨트롤러에 맞는 실행 방식을 제공합니다.
    • 또한, 핸들러 어댑터는 요청을 처리하는 실제 컨트롤러를 호출하기 전에 인터셉터와 같은 공통 작업을 처리할 수 있는 흐름을 제공한다.
  2. 핸들러 호출
    • 핸들러 어댑터는 HandlerMapping에 의해 반환된 컨트롤러를 실행하는 역할을 한다. 예를 들어, @RequestMapping 어노테이션을 붙인 메서드나, Controller 인터페이스를 구현한 클래스를 호출하여 그 로직을 실행한다.
    • 이때, 핸들러 어댑터는 컨트롤러 메서드에 필요한 파라미터에 데이터를 바인딩하는 역할도 한다. (@RequestParam, @PathVariable, @RequestBody, @ModelAttribute)
  3. 핸들러의 반환 값 처리
    • 컨트롤러에서 반환된 객체(일반적으로 ModelAndView 또는 뷰 이름 등)는 핸들러 어댑터에 의해 DispatcherServlet로 전달된다.
    • DispatcherServlet은 반환된 값에 따라 적절한 후속 작업을 수행한다.
    • 반환 값이 뷰 이름이면 뷰 리졸버(ViewResolver)를 사용하여 해당 뷰를 찾고 렌더링할 수 있도록 한다.
    • 반환 값이 모델 객체인 경우, 이 모델 객체를 뷰에 전달하는 역할을 한다.

2️⃣ DispatcherServlet의 동작과정

 

 

 

  1. 핸들러 조회: 핸들러 매핑을 통해 요청 URL에 매핑된 핸들러(컨트롤러)를 조회한다.
  2. 핸들러 어댑터 조회: 핸들러를 실행할 수 있는 핸들러 어댑터를 조회한다.
  3. 핸들러 어댑터 실행: 핸들러 어댑터를 실행한다.
  4. 핸들러 실행: 핸들러 어댑터가 실제 핸들러를 실행한다.
  5. ModelAndView 반환: 핸들러 어댑터는 핸들러가 반환하는 정보를 ModelAndView로 변환해서 반환한다.
  6. viewResolver 호출: 뷰 리졸버를 찾고 실행한다.
  7. View 반환: 뷰 리졸버는 뷰의 논리 이름을 물리 이름으로 바꾸고, 렌더링 역할을 담당하는 뷰 객체를 반환한다. 
  8. 뷰 렌더링: 뷰를 통해서 뷰를 렌더링 한다.