MVC 디자인패턴
Spring MVC

。스프링 어플리케이션을 Model, View, Controller로 구분하여 각 역할에 맞게 코드를 작성하는 방식
▶ MVC 디자인 패턴을 스프링 어플리케이션으로 구현
▶ MVC 디자인 패턴 중 Model2 Architecture + Front Controller 패턴을 기반
。View : JSP or Thymeleaf
。Model : Service , Repository 클래스
。Controller : @Controller
。 현재는 View와 Model의 경우 잘 사용하지않음
▶ View는 프론트엔드 , Model의 비즈니스 로직은 Service , Repository 역할의 클래스에서 수행
Spring MVC 특징
Dispatcher Sevlet, 메타어노테이션을 통한 요청, 응답과정 단순화
。Spring MVC의 Dispatcher Sevlet을 통해 받은 모든 요청을 @Controller를 선언한 Controller Class의 @GetMapping 등의 어노테이션으로 라우팅하여 손쉽게 Http Request와 Http Response를 수행하므로 HttpServlet를 사용하지 않는다.
▶ Spring이 HttpServlet을 추상화한 계층을 제공
- 과거
Spring은 Spring MVC를 통해 ModelMap과 JSP를 통해 프론트엔드 영역까지 담당
。현재는 백엔드와 분리되어 View, Model을 사용하지는 않음.
▶ View는 SPA 방식을 통한 프론트엔드 ( = React , ... )으로 대체
▶ Model의 비즈니스 로직은 Service , Repository 역할의 클래스에서 작성
。Spring은 주로 API를 구축하여 클라이언트( = 프론트엔드 어플리케이션 ) 에 대해 데이터 요청을 할 경우 DB에서 꺼내서 JSON으로 서빙하는 역할을 수행
Spring MVC 구성요소

Dispatcher Servlet ( = Front Controller ) :
。Application의 가장 앞단에서 Client로부터의 요청을 수신하여 중계하는 Controller
▶ 요청부터 응답까지의 전반적인 처리과정을 관리
▶ Model2 구조의 Front Controller
。root url["/"]을 Mapping 하므로, Client가 서버에 요청을 전송하는 url에 관계없이 모든 HTTP Request가 가장 먼저 수신
。@RequestMapping, @GetMapping , ... ( HandlerMapping & HandlerAdapter )를 통해 수신한 요청의 URL에 적합한 Controller를 식별 및 요청을 전달
▶ Client로부터의 모든 요청을 수신 후 요청의 처리를 적합한 개별 Controller로 라우팅

。Spring Boot에 의해 Auto-Configuration이 수행 시 Dispatcher Servlet이 자동으로 Spring Bean으로 등록
HandlerMapping
。Dispatcher Servlet에서 수신한 요청의 URL을 기반으로 어떤 Controller가 처리할지 결정
▶ @RequestMapping에 포함
HandlerAdapter
。HandlerMapping을 통해 요청을 처리할 Controller를 식별 시 요청을 전달
▶ @RequestMapping에 포함
Controller( = Handler )
。Dispatcher Servlet에서 HandlerAdapter를 통해 전달된 클라이언트의 실질적인 요청을 처리하는 @RequestMapping, @GetMapping, ... 이 선언된 method
▶ @Controller 클래스 내 포함
。Method 내 정의된 로직으로 요청을 처리 후 반환
▶ 레이어드 아키텍처를 통한 Controller -> Service -> Repository 순서로 단방향 의존하여 Business logic을 처리
Controller , Service , Repository
。 처리결과를 다시 DispatcherServlet으로 반환
▶ View Resolver를 사용하지않는 REST API의 경우 @ResponseBody를 선언하여 문자열 또는 JSON 형태로 반환
▶ Model과 View를 사용하는 경우 Controller에서 반환된 문자열을 기반으로 View Resolver를 통해 조회된 템플릿으로 동적으로 생성된 HTML 페이지를 반환
ViewResolver
。Controller에서 반환된 문자열을 기준으로 src/main/resources/templates에서 적절한 템플릿 파일을 찾는 객체
▶ Controller에서 @ResponseBody 선언 시 작동 X
View
。JSP , Thymeleaf와 같은 템플릿 엔진으로서 화면을 렌더링.
Spring MVC 원리

。 보라색 : 개발자가 작성하는 logic
。 파란색 : 스프링이 처리하는 logic
▶ 개발자는 Controller , Service , Repository 역할의 Class를 집중해서 개발
클라이언트가 서버 URL에 HTTP Request를 전송
Dispatcher Servlet에서 Client로 부터의 Http Request를 수신
Dispatcher Servlet에서 HttpRequest의 URL을 기반으로 HandlerMapping을 통해 적절한 Controller를 식별
。 localhost:8080/login 일 경우, @RequestMapping("Login")이 선언된 Controller Method를 식별.
HandlerAdapter를 통해 해당 Controller로 요청을 전달
Controller에서 요청에 대한 작업을 처리
。레이어드 아키텍처에 따라 Controller -> Service -> Repository로 고수준 클래스에서 저수준 클래스로 단방향 의존하면서 요청 DB의 데이터를 요청 및 Business Logic을 처리
▶ Repository가 Service를 의존할 수 없다.
Controller, Service, Repository
View Resolver를 활용하여 Model과 View를 통해 브라우저에서 렌더링할 HTML 페이지를 생성하여 클라이언트에게 반환하는 경우
- 해당
Controller에서 ModelMap을 생성 및 View의 이름을 return
。Controller Method의 매개변수에 ModelMap model을 생성하여 model.put("name",name);을 통해 ModelMap에 name라는 변수를 생성하여 전달값을 넣고, "Login" 문자열을 return.
return된 문자열을 기반으로 Rendering 할 적절한 Template 파일을 ViewResolver로 식별 후 동적으로 렌더링할 View를 생성
。application.yml에서 prefix, suffix를 설정하고, src/main/resources/templates에서 해당 Login으로 시작하는 jsp파일을 식별
- 생성된
View를 Controller -> Dispatcher Servlet을 거쳐 Http Response를 통해 클라이언트의 브라우저로 응답하여 렌더링
。HTML 페이지를 생성하여 클라이언트의 브라우저로 응답
REST API로서 데이터만 클라이언트에게 반환하는 경우
。객체의 경우 DTO로서 일반 POJO를 사용
Controller에 @ResponseBody 선언 및 반환할 데이터를 설정
。@ResponseBody을 선언하는 경우 View Resolver가 작동하지 않게됨.
▶ 클라이언트에게 반환값으로 온전한 문자열을 반환
▶ 객체를 반환하는 경우 Jackson 라이브러리를 통해 JSON으로 변환되어 반환
Controller에서 반환된 데이터를 Controller -> Dispatcher Servlet를 거쳐서 클라이언트에게 반환