[Spring] Spring MVC란?
1. MVC 패턴이란?
- 정의
- 애플리케이션을 개발할 때 사용하는 디자인 패턴
- 애플리케이션의 개발 영역을 Model, View, Controller로 구분하여 각 역할에 맞게 코드를 작성하는 개발 방식
- 장점
- UI 영역과 도메인(비즈니스 로직) 영역으로 구분되어 서로에게 영향을 주지 않으면서 개발과 유지보수가 가능함
- 구조
- Model 모델
- 애플리케이션의 정보(데이터)를 나타냄
- 웹 애플리케이션이 클라이언트의 요청을 전달받으면 요청 사항을 처리하기 위한 작업을 하는데,
이때 클라이언트에게 응답으로 돌려주는 작업의 처리 결과 데이터를 모델이라고 함
- View 뷰
- 텍스트, 체크박스 항목 등과 같은 사용자 인터페이스 요소
- 모델을 이용하여 웹 브라우저와 같은 애플리케이션의 화면에 보이는 리소스를 제공
- 스프링 MVC에 포함된 View 기술
- HTML 페이지 출력
- PDF, Excel 등의 문서 형태로 출력
- XML, JSON 등 특정 형식의 포맷으로 변환
- Controller 컨트롤러
- 데이터와 비즈니스 로직 사이의 상호동작을 관리함
- 클라이언트 측의 요청을 직접적으로 전달받는 엔드포인트
모델과 뷰의 중간에서 상호작용을 해줌 - 클라이언트 측의 요청을 전달받아 비즈니스 로직을 거친 후, 모델 데이터가 만들어지면 이 모델 데이터를 뷰로 전달하는 역할을 함
2. MVC 패턴을 왜 사용할까?
하나의 서블릿이나 JSP만으로 비즈니스 로직과 뷰 렌더링까지 모두 처리하게 되면 너무 많은 역할을 하게 된다.
또한 비즈니스 로직과 뷰 사이에 변경의 라이프 사이클이 다른데 이걸 하나에서 처리하게 되면 문제가 생긴다.
👉 유지보수가 어려워진다.
사용자가 보는 페이지, 데이터 처리, 그리고 이 둘을 중간에서 제어하는 컨트롤.
이렇게 세 가지로 구성되는 하나의 애플리케이션을 만들면 각각 맡은 역할에만 집중을 할 수 있게 된다.
👉 장점
- 시스템 결합도를 낮출 수 있음
- 유지보수가 쉬움
- 중복 코드를 제거할 수 있음
- 애플리케이션의 확장성 및 유연성이 증가함
3. Spring MVC란?
- 등장 배경
Spring MVC에 대해 이야기하기 앞서 그간의 역사를 살펴보자.
우리가 최근 사용하고 있는 MVC 패턴은 MVC1, MVC2 아키텍쳐에서 발전된 패턴이다.
❕MVC1
위는 MVC1 패턴의 구조를 나타낸 사진이다.
MVC1 패턴이란 사용자로부터 요청이 들어오면 DB로부터 필요한 데이터를 받은 모델 객체(Java Bean)를 JSP 페이지(View)에 담아 응답으로 보내는 패턴이다.
사진에서 보듯이 MVC1에서는 JSP가 View와 Controller의 역할을 모두 담당한다.
따라서 JSP 페이지 내에 너무 많은 코드가 들어가게 된다.
단점 👉 코드의 가독성이 떨어지고, 코드가 복잡해진다.
보완 👉 Controller 역할을 하는 Servlet이 추가된 MVC2 패턴이 등장하게 되었다.
❕MVC2
MVC2 패턴은 MVC1 패턴과 달리 요청을 컨트롤러(Servlet)가 먼저 받는다.
서블릿은 요청에 대한 비즈니스 로직을 처리한 후, 이를 JSP 파일에 반영하는 역할을 수행한다.
단점 👉 MVC2는 MVC1 패턴보다 구조가 복잡해질 수 있다.
보완 👉 프레임워크가 발전하였다. 예) 스프링 프레임워크
- 정의
- Spring MVC는 MVC2 모델을 기반으로 한 웹 모듈
- 스프링 프레임워크에서 MVC2 모델을 좀 더 발전시킨 것
- 동작
- 1. 프론트 컨트롤러(Front Controller)가 우선적으로 클라이언트로부터 모든 요청을 받게 됨
- 2. 실제 요청의 처리는 개별 컨트롤러 클래스(Handler)로 위임함
- 3. Handler는 DI를 통해 생성해둔 Bean을 통해 비즈니스 로직 처리 결과를 Model에 담아 다시 프론트 컨트롤러로 보냄
- 4. 프론트 컨트롤러는 받은 Model을 View 템플릿으로 전달하여 반영시킴
- 5. 최종적으로 클라이언트로 보낼 화면을 응답 결과로 전송함
4. Spring MVC 구조
- 구조
DispatcherServlet❓
- Front Controller의 역할을 수행하며 Request를 각각의 Controller에게 위임함
- 가장 앞단에서 클라이언트의 요청을 처리하는 Controller
- 요청부터 응답까지 전반적인 처리 과정을 통제함
- DispatcherServlet을 Front Controller로 설정하는 방법
- web.xml에 명시한다.
- org.springframework.web.WebApplicationInitializer 인터페이스를 구현한다.
HandlerMapping❓
- 요청을 직접 처리할 컨트롤러를 탐색함
- 구체적인 Mapping은 xml 파일이나 java config 관련 어노테이션 등을 통해 처리 가능
HandlerAdapter❓
- 매핑된 컨트롤러의 실행을 요청함
Controller❓
- DispatcherServlet이 전달해준 HTTP 요청을 처리하고 결과를 Model에 저장함
- 직접 요청을 처리하며 처리 결과를 반환함
- 결과가 반환되면 HandlerAdapter가 ModelAndView 객체로 변환되며,
여기에는 View Name과 같이 응답을 통해 보여줄 View에 대한 정보와 관련된 데이터가 포함되어 있음
- Name과 같이 응답을 통해 보여줄 View에 대한 정보와 관련된 데이터가 포함되어 있음
ModelAndView❓
- Controller에 의해 반환된 Model과 View가 Mapping된 객체
View Resolver❓
- View Name을 확인한 후, 실제 컨트롤러부터 받은 로직 처리 결과를 반영할 View 파일(jsp)을 탐색함
View❓
- 로직 처리 결과를 반영한 최종 화면을 생성함
- 동작 구조
- User → DispatcherServlet
- 클라이언트가 서버에 요청 👉 Front Controller인 DispatcherServlet 클래스가 요청을 받음
- DispatcherServlet ↔ HandlerMapping
- DispatcherServlet은 프로젝트 파일 내의 servlet-context.xml 파일의 @Controller 인자를 통해 등록한 요청 위임 컨트롤러를 찾아 매핑된 컨트롤러가 존재하면 @RequestMapping을 통해 요청을 처리할 메소드로 이동함
- DispatcherServlet ↔ Controller
- 컨트롤러는 해당 요청을 처리한 Service(서비스)를 받아 비즈니스 로직을 서비스에게 위임함
- Service는 요청에 필요한 작업을 수행하고, 요청에 대해 DB에 접근해야 한다면 DAO에 요청하여 처리를 위임함
- DAO는 DB 정보를 DTO를 통해 받아 서비스에게 전달함
- 서비스는 전달받은 데이터를 컨트롤러에게 전달함
- 컨트롤러는 Model(모델) 객체에게 요청에 맞는 View 정보를 담아 DispatcherServlet에게 전송함
- DispatcherServlet ↔ ViewResolver
- DispatcherServlet는 ViewResolver에게 전달받은 View 정보를 전달함
- ViewResolver는 응답할 View에 대한 JSP를 찾아 DispatcherServlet에게 전달함
- DispatcherServlet → View → User
- DispatcherServlet은 응답할 뷰의 Render를 지시하고 뷰는 로직을 처리함
- DispatcherServlet은 클라이언트에게 Rending된 뷰를 응답하며 요청을 마침
참고