MVC 패턴이란?
소프트웨어 디자인 패턴 중 하나로, 다음 세가지로 구성된다
Model
- 모델은 뷰에 출력할 데이터를 담아둔다.
- 모델은 뷰나 컨트롤러에 대해 알지 못한다.
View
- 뷰는 모델에 담겨있는 데이터를 활용해 화면을 그린다.
- 뷰는 모델이나 컨트롤러에 대해 알지 못한다.
Controller
- 컨트롤러는 요청을 받아 비즈니스 로직을 실행하고, 뷰에 결과 데이터를 모델에 담아 전달한다.
- 때문에 컨트롤러는 뷰와 모델을 모두 알고 있어야 한다.
- 모델과 뷰가 서로의 존재를 모르기 때문에, 컨트롤러는 둘 사이에서 사용자 입력과 데이터 전달을 담당하며 중재하는 역할을 한다.
Spring MVC 구조
DispatcherServlet
-
Front Controller의 역할을 한다.
-
가장 앞단에서 클라이언트의 요청을 처리하는 Controller로, 전반적인 처리 과정을 통제한다.
-
DispatcherServlet은 HttpServlet을 상속받아 서블릿으로 동작한다.
Servlet이란?
서블릿(Servlet)이란 동적 웹 페이지를 만들 때 사용되는 자바 기반의 웹 애플리케이션 프로그래밍 기술이다. 서블릿은 웹 요청과 응답의 흐름을 간단한 메서드 호출만으로 체계적으로 다룰 수 있게 해준다.
주요 특징은 다음과 같다.
- 클라이언트의 Request에 대해 동적으로 작동하는 웹 어플리케이션 컴포넌트
- 기존의 정적 웹 프로그램의 문제점을 보완하여 동적인 여러 가지 기능을 제공
- JAVA의 스레드를 이용하여 동작
- MVC패턴에서 컨트롤러로 이용됨
- 컨테이너에서 실행된다
- 보안 기능을 적용하기 쉬움
-
서블릿이 호출되면 HttpServlet이 제공하는 service()가 호출된다.
-
스프링 MVC는 FrameworkServlet.service()를 시작으로 여러 메서드가 호출되며 최종적으로 DispatcherServlet.doDispatch()가 호출된다.
HandlerMapping
- 요청을 직접 처리할 컨트롤러를 탐색한다.
- 구체적인 매핑은 xml 파일이나 java config 관련 어노테이션 등을 통해 처리할 수 있다
HandlerAdapter
- 매핑된 컨트롤러 Handler 메소드의 실행을 요청한다.
Handler(Controller)
- Spring MVC에서 Controller = Handler라고 생각하면 편하다.
- 핸들러는 DispatcherServlet가 전달해준 HTTP 요청을 처리하고 결과를 Model에 저장한다.
ModelAndView
- ModelAndView는 controller에 의해 반환된 Model과 View가 Wrapping된 객체이다.
ViewResolver
- ViewResolver는 View name에 맞는 View를 찾아 View 객체를 생성한다. 이 객체를 이용해 View 내용을 생성하게 된다.
HttpMessageConverter
- HttpMessageConverter은 @RequestBody, @ResponseBody등을 사용하게 되면 동작하는데, JSON 데이터를 HTTP 메시지 바디 내 직접 읽거나 쓰는 경우 사용한다.
- String 문자 처리에는 StringMessageConverter, 객체 처리에는 MappingJackson2HttpMessageConverter를 사용한다.
- 응답의 경우 클라이언트의 Accept 헤더와 컨트롤러의 반환 타입을 조합해MessageConverter가 선택된다.
- HttpMessageConverter는 ArgumentResolver와 ReturnValueHandler에서 작동한다.
ArgumentResolver
- 컨트롤러 메소드의 파라미터를 전달할 때 작동한다.
- @RequestParam, @RequestBody, @Model 등을 이용해 파라미터를 전탈할 때 사용된다.
- 이때 HttpMessageConverter를 사용해 값들의 타입을 확인하고, 알맞은 객체로 변환한다.
ReturnValueHandler (HandlerMethodReturnValueHandler)
- @ResponseBody, HttpEntity를 처리한다.
- 반환값을 HttpMessageConverter를 이용해 처리하고, Http 메시지에 입력한다.
Spring MVC 동작 원리 (View 반환 시)
- 클라이언트가 서버에 요청을 보내면, DispatcherServlet 클래스가 요청을 받는다.
- DispatcherServlet은 요청을 처리할 컨트롤러에 대한 검색을 HandlerMapping 인터페이스에게 요청한다.
- HandlerMapping은 클라이언트 요청에 해당하는 컨트롤러 정보를 찾아 DispatcherServlet에게 응답한다
- 이때 컨트롤러 정보에는 해당 컨트롤러 안의 Handler 메소드 정보가 포함된다.
- Handler 메소드란 컨트롤러 클래스 내에서 구현된, 요청을 처리해주는 메소드이다.
- 컨트롤러를 찾은 후, 해당 요청을 처리할 Handler 메소드를 찾아 호출해야 하는데, 이를 직접 호출하는 방식이 아닌 HandlerAdapter에게 책임을 위임한다.
- HandlerAdapter은 DispatcherServlet 요청, 컨트롤러 정보를 가지고 해당 컨트롤러의 Handler 메소드를 호출한다.
- 컨트롤러의 Handler 메소드는 비즈니스 로직을 처리한 후 결과를 HandlerAdapter에게 반환한다.
- HandlerAdapter는 반환받은 결과를 ModelAndView 객체로 변환해 DispatcherServlet에 전달한다.
- DispatcherServlet은 반환받은 ModelAndView 중 View name을 가지고 ViewResolver를 호출한다.
- ViewResolver에서는 View name을 통해 해당하는 View를 찾아 View 객체를 리턴한다
- DispatcherServlet은 받은 View 객체에 Model 데이터를 넘겨주면서 최종적으로 클라이언트에게 전달할 응답 데이터를 생성한다.
- DispatcherServlet은 받은 응답데이터를 마지막으로 클라이언트에 응답한다.
Spring MVC 동작 원리 (Data 반환 시)
- HandlerAdapter에서 Handler 함수를 호출할 때, Parameter(@RequestBody, @Model, @RequestParam)가 있다면 ArgumentResolver를 호출한다.
- Argument Handler에서는 HttpMessageConverter를 호출해 parameter 값을 확인하고 객체를 생성한다.
- Controller에서 요청을 처리하고 반환할 시, @ResponseBody가 달려있다면 ReturnValueHandler를 호출한다.
- ReturnValueHandler에서는 HttpMessageConverter를 호출해 반환값을 확인하고 Http 메시지에 입력한다.
- HandlerAdapter에서 값을 반환한다.