본문 바로가기

Language & Framework/Spring

MVC패턴이란? Spring MVC의 기본 흐름을 알아보자.

 

용수철 이미지 올리려다가 참았다.

MVC?

 

MVC (Model-View-Controller)는 사용자 인터페이스, 데이터 및 논리 제어를 구현하는데 널리 사용되는 소프트웨어 디자인 패턴이다.

 

1. Model

애플리케이션에 어떤 데이터를 포함해야하는 지를 정의한다.

변경에 대한 처리 방법만을 구현해야하며 뷰나 컨트롤러에 대한 정보를 가지고 있어서는 안된다.

예 ) 쇼핑몰의 경우 : 상품 품목, 가격, 이미지 등

 

2. View

단어 그대로 보여지는 것을 담당하는 부분으로 애플리케이션의 데이터를 보여주는 방식을 정의한다. (UI)

뷰는 모델이 가지고 있는 정보를 따로 저장하지 않으며 컨트롤러에 대해 알 수 없고 변경이 일어난 것에 대한 처리 방법만을 구현해야 한다.

 

3. Controller

컨트롤러는 애플리케이션에서 사용자의 입력에 대한 응답으로 모델/뷰를 업데이트하는 로직을 포함한다.

모델과 뷰는 분리되지만 컨트롤러는 모델과 뷰를 알고 변경사항을 모니터링할 수 있어야 한다.

예 ) 좋아요 버튼을 누르면 해당 입력값을 모델에 전달해준다

 

위 내용을 보면 Controller는 Model과 View를 알고 핸들링하고 있지만 Model과 View는 완벽하게 분리되어 있다..

이것이 바로 MVC의 핵심인 "관심사의 분리"이다. 그리고 MVC 패턴을 이용한 가장 큰 장점은 "유지보수의 편리성"이다.

MVC 패턴을 잘 활용하면 객체지향의 장점의 극한으로 이끌어낼 수 있다.

 

 

 

 

 

 

MVC Model 1

 

요즘 세상에 이렇게 개발하게 될 일은 없다고 봐도 무방하기 때문에 크게 중요하지는 않지만 일단 알고 넘어가자.

우리가 일반적으로 MVC 패턴이라고 생각하는 것은 스프링 MVC패턴에 해당하는 MVC 모델2이고, View(주로 JSP)와 Controller가 함께 공존하던 MVC model 1이라는 것이 존재했다.

MVC model 1에서는 Controller에 해당하는 자바 코드와 View에 해당하는 JSP 코드, 그리고 html, css코드가 섞여 있어서 유지보수가 굉장히 힘들다.

이것도 처음 나왔을 시절에는 나름 혁신이였을 수 있겠으나.. 맨땅에서 MVC 모델2까지 구현해나가며 느낀 점은 대선배님들에 대한 무한한 존경과 감사의 마음 뿐 ^^..

빠른 작업이 가능해서 작은 프로젝트에는 오히려 유리할 수 있다고 하는데, 오직 view만 담당하는 리액트 혹은 자바스크립트에서도 로직을 철저하게 나누려고 하는 판국에.. 내가 만약 MVC model 1의 방식으로 코드를 작성했다면, 다시는 그 코드를 읽고 싶지 않을 것 같다.

 

 

 

 

 

Spring MVC

 

일반적으로 우리가 MVC 패턴이라고 부르는 MVC 모델2는 이런 형태로 되어있으며 스프링 MVC는 Front Controller Pattern을 구현하고 있다. 그림을 보면 Dispatcher Servlet이라는 서블릿 하나가 중앙에서 클라이언트가 보낸 Request에 대한 모든 흐름을 제어하고 있다. 이것이 바로 Spring MVC의 핵심이다.

 

그림으로 로직을 봐도 Model1보다 Spring MVC가 더 복잡하고 어려워 보일 수도 있다.

하지만 힘들었던 건 MVC Model2를 설계한 개발자들이고 우리한테는 이것이 훨씬 편하다. ㅎㅎ

 

흐름을 풀어서 설명하자면 다음과 같다.

 

1. 클라이언트로부터 HTTP Request가 들어온다.

 

2. Dispatcher Servlet이 우선 HTTP Request 요청을 받는다.

 

3. 해당 HTTP Request를 적절한 Controller에 보내기 위해 HandlerMapping이 탐색을 시작한다. 참고로 탐색에는 우선순위가 있다. 아래의 흐름대로 진행된다. 흐름이 있다는 것 뿐이지 99% Annotation을 사용하기 때문에 별 의미는 없다.

  3-1. RequestMappingHandlerMapping : Annotation 기반의 Controller 중에서 탐색한다.

  3-2. BeanNameUrlHandlerMapping : Spring Bean의 이름을 기반으로 탐색한다.

  3-3. HttpRequestHandler : 가장 날것의 서블릿과 비슷한 형태로 HttpRequestHandler를 구현한 Controller 중에서 탐색한다.

 

4. HandlerMapping이 적절한 Controller를 찾았으면 해당 Controller에 알맞는 Handler Adapter를 찾는다. 이것 또한 아래의 순서로 탐색한다.

  4-1. RequestMappingHandlerAdapter : @RequestMapping 기반. 99.9% 이것을 사용하니 아래 내용은 그냥 교양이라고 생각하자.

  4-2. HttpRequestHandler : 위와 마찬가지로 HttpRequestHandler를 구현한 Controller.

  4-3. SimpleHandlerAdapter : Controller를 구현한 Controller.. 말이 좀 이상하게 느껴질 수 있지만 실제로 그렇다. 아무튼 Controller를 구현한 Controller를 뜻한다.

 

5. 드디어 Controller에서 요청을 처리하고 DispatchServlet으로 돌아온다.

 

6. 이제 View에 데이터를 전달해줘야 하는데, 어떤 View에 데이터를 전달해줘야 할 지 모르기 때문에 viewResolver에서 View의 정보를 가져온다. 참고로 스프링부트에서는 아래의 viewResolver를 자동으로 등록해준다.

  6-1. BeanNameViewResolver : 빈 이름으로 View를 찾아서 반환한다.

  6-2. InternalResourceViewResolver : JSP를 처리할 수 있는 View를 반환한다.

 

7. View는 데이터를 받아 UI를 그리고 클라이언트에게 응답한다.

 

 

 

 

 

Spring MVC의 장단점은 MVC model 1을 뒤집어 놓았다고 생각하면 된다. 유지보수가 편하지만 처음 생산성은 떨어진다.

하지만 웹개발에서 말하는 MVC의 99.99%는 Spring MVC 같은 MVC model 2다.

그리고 둘 다 사용해보면 정말.. MVC model 2를 처음 접하면 얼마나 감동적이고 감사하는 마음을 가지게 되는지 모른다..

 

물론 이런 MVC model 2의 탄생도 오래되었고 Model과 View 사이의 의존성이 존재한다는 단점 때문에 MVVM, MVP 패턴 등도 생겨났다. MVP 패턴..은 잘 모르겠고 언젠가 MVVM은 공부해보고 싶다. MVVM 방식을 활용한 Back-end 라이브러리가 바로 WebFlux이다.