-
MVC 패턴이란? (스프링 MVC)Spring Framework 2022. 1. 4. 00:01
이전에 포스팅했던 Spring Framework의 특징 중 하나인 MVC 패턴에 대하여 알아보겠습니다.
https://junuuu.tistory.com/35?category=968779
MVC 패턴이란?
Model, View, controller의 약자로 애플리케이션을 세 가지의 역할로 구분하는 디자인 패턴입니다.
디자인 패턴이란?
프로젝트를 개발할 때 유지보수를 하고 쉽고 다른 개발자들과 서로 공유하기 쉽도록 만든 규약입니다.
그러면 Model, View, Controller는 무엇을 의미할까요?
Model이란?
애플리케이션의 정보, 즉 데이터나 비즈니스 로직을 제공합니다.
비즈니스 로직이란?
사용자눈에는 보이지 않지만, 사용자가 바라는 결과물을 제공하는 코드입니다.
아주 간단하게 예를 들어 보겠습니다.
1. 사용자가 "비밀번호 찾기" 버튼을 눌러서 비밀번호를 찾기를 원한다.
2. 사용자의 아이디를 입력받고 데이터베이스를 연결하여 해당 아이디의 비밀번호를 조회한다.
3. 데이터베이스에서 조회한 비밀번호를 사용자에게 보여준다.
이 일련의 과정들을 구현하기 위한 코드를 비즈니스 로직이라고 할 수 있습니다.
View란?
모델에 포함된 데이터의 시각화
뷰는 사용자에게 보여주는 인터페이스, 즉 화면이다.
Controller란?
뷰와 모델의 역할을 분리하는 전체적인 데이터의 흐름 제어
View와 Model이 직접적인 상호 소통을 하지 않도록 관리합니다.
사용자가 접속한 URL에 따라서, 로직을 수행 후 결과 Model을 View에 넘겨준다.
MVC 패턴의 등장 배경
이전에는 View에서 모든 것을 처리했기 때문에 로직 + 출력 코드가 한 페이지에 삽입되었습니다
코딩 자체는 쉬웠지만 유지보수에 많은 어려움을 겪었습니다.
이를 MVC1 패턴이라고 합니다.
따라서 유지보수가 어려운 MVC1패턴과 다르게 비즈니스 로직과 출력을 분리하여 코드의 결합도를 낮추어 재사용성을 높이고 개발자들 간의 커뮤니케이션 효율성을 높일 수 있습니다.
이를 MVC2 패턴이라고 하며, 우리가 흔히 말하는 MVC 패턴은 MVC2 패턴입니다.
MVC 패턴의 흐름
1. 사용자가 원하는 기능을 처리하기 위해 웹브라우저가 컨트롤러에게 요청을 보냅니다.
2. 컨트롤러는 모델에게 데이터를 요청합니다.
3. 컨트롤러는 모델에게 받은 데이터를 View로 전달합니다.
4. View는 컨트롤러를 통하여 사용자에게 보여줄 데이터를 전달받고 결과 화면을 보여줍니다.
Spring MVC 패턴의 흐름
1. DispatcherServlet이 프런트 컨트롤러의 역할을 하여 웹브라우저의 모든 요청을 받습니다.
2. 요청을 받은 DispatcherServlet이 HandlerMapping에게 URL과 매핑되는 Controller의 메서드를 물어보고 결정합니다.
3. 결정받은 Controller는 로직을 수행한 후, View의 이름을 반환합니다. 이 과정에서 Model이 생성되어 View에게 같이 전달됩니다.
4. DispatcherServlet은 Controller가 반환한 View의 이름을 View Resolver에게 확인받아 물리적 View를 검색합니다.
5. 결정된 View는 Model 정보와 함께 화면을 표시한 후, Dispatcher Servelt에 보냅니다.
6. Dispatcher Servelt은 결과를 최종 출력합니다.
아래 2개의 그림 중 이해가 더 잘되는 그림을 보고 이해하시면 좋습니다.
Servelt이란?
클라이언트가 어떠한 요청을 하면 그에 대한 결과를 다시 전송해주어야 하는데, 이러한 역할을 하는 자바 프로그램이라고 합니다. 추후에 더 자세하게 다루어 보도록 하겠습니다.
이전 시간에는 스프링 부트 Welcome Page를 만들었습니다.
https://junuuu.tistory.com/45?category=968779
그러면 코드를 보면서 실제로 MVC 패턴이 어떻게 적용되는지 알아보겠습니다.
Controller
import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestParam; @Controller public class HelloController { @GetMapping("hello") public String hello(Model model) { model.addAttribute("data", "hello!"); return "hello"; } @GetMapping("hello-mvc") public String helloMvc(@RequestParam("name") String name,Model model) { model.addAttribute("data", name); return "hello-template"; } }
이전 시간에는 없던 @GetMapping("hello-mvc") 어노테이션을 추가하여 /hello-mvc에 대한 요청을 받을 수 있게 하였습니다.
@RequestParam("name") String name 부분은 사용자가 넘겨준 데이터를 이용하여 동적으로 웹에 표시할 수 있도록 합니다.
@RequestParam("name") String name
위와 같은 형식으로 사용됩니다.
위의 코드가 정상적으로 동작하기 위해서는 hello-template.html을 src/main/resources/templates/ 경로에 추가해야 합니다.
View
<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org"> <head> <title>Hello</title> <meta http-equiv="Content-Type" content="text/html; charset = UTF-8"/> </head> <body> <p th:text="'안녕하세요.' + ${data}" > 안녕하세요. 손님</p> </body> </html>
1. DispatcherServlet이 프런트 컨트롤러의 역할을 하여 웹브라우저의 요청을 받습니다.
2. 요청을 받은 DispatcherServlet이 HandlerMapping에게 /Hello와 매핑되는 Controller의 메서드를 물어보고 결정합니다.
3. /Hello와 매핑되므로 Controller는 hello 메서드를 수행하여 , View의 이름인 hello를 반환합니다. 이 과정에서 Model이 생성되어 View에게 같이 전달됩니다.
4. 이때 만약 /Hello-mvc? name=spring!! 과 같은 URL이 들어왔다면 /Hello-mvc와 매핑되므로 Controller는 helloMvc 메서드를 수행하여, View의 이름은 hello-template을 반환합니다. 이 과정에서 Model이 생성되어 View에게 같이 전달됩니다.
/Hello-mvc는 /Hello와 다르게 queryString을 의미하는? name=spring!! 도 포함되는데 여기서 name은 변수를 의미하고 spring!! 은 변수의 값을 의미합니다.
5. DispatcherServlet은 Controller가 반환한 View인 Hello를 View Resolver에게 확인받아 물리적 View를 검색합니다.
물리적 View = templates/hello.html
6. 결정된 View는 Model 정보와 함께 화면을 표시한 후, Dispatcher Servelt에 보냅니다.
결정된 View
templates/hello.html
Model 정보
name = spring!!
7. Dispatcher Servelt은 결과를 최종 출력합니다.
아래 그림은 위의 전체적은 흐름과 비슷합니다.(예시 /hello-mvc로 요청이 들어왔을 때)
출처
https://docs.spring.io/spring-framework/docs/current/reference/html/web.html#spring-web
https://www.youtube.com/watch?v=es1ckjHOzTI
https://www.youtube.com/watch?v=ogaXW6KPc8I
https://www.podo-dev.com/blogs/63
https://chanhuiseok.github.io/posts/spring-3/
https://mangkyu.tistory.com/14 [MangKyu's Diary]
https://hongku.tistory.com/119
'Spring Framework' 카테고리의 다른 글
서블렛(Servlet)이란? (0) 2022.01.09 템플릿엔진이란? (0) 2022.01.07 스프링부트 Welcome Page 만들기(스프링부트 hello 출력하는 페이지 만들기) (0) 2021.12.31 build.gradle 파일 분석 (0) 2021.12.29 이클립스로 스프링부트 프로젝트 시작하는 법(Spring Initializr) - Gradle 에러 디버깅 (0) 2021.12.26