이 글에서는 웹 애플리케이션에서 흔히 사용되는 디자인 패턴인 MVC 패턴과, Spring 에서는 어떻게 이 패턴을 구현하는지에 대해 알아보고자 합니다.
디자인 패턴: MVC 패턴
MVC란 Model-View-Controller의 약자로, 소프트웨어 디자인 패턴 중 하나이다.
MVC 패턴은 소프트웨어를 구성하는 요소들을 Model, View, Controller로 구분하여 각각의 역할을 분리한다.
Model
- 데이터와 비즈니스 로직을 담당한다.
- 데이터베이스와 연동하여 데이터를 저장하고 불러오는 등의 작업을 수행한다.
View
- 사용자 인터페이스를 담당한다.
- 사용자가 보는 화면과 버튼, 폼 등을 디자인하고 구현한다.
Controller
- Model과 View 사이의 상호작용을 조정하고 제어한다.
- 사용자의 입력을 받아 Model에 전달하고, Model의 결과를 바탕으로 View를 업데이트한다.
MVC 패턴은 소프트웨어를 구성하는 요소들을 분리함으로써 코드의 재사용성과 유지보수성을 높이고, 개발자들 간의 협업을 용이하게 한다. 따라서 소프트웨어를 개발할 때, MVC 패턴을 적용하여 구조를 잘 설계하는 것이 중요하다.
Spring MVC
Spring Web MVC
Spring Web MVC는 전통적인 Model-View-Controller 패턴을 기반으로 하는 웹 프레임워크로, 서버 사이드 애플리케이션 개발을 용이하게 한다. Spring Web MVC는 다음과 같은 주요 구성 요소로 이루어져 있다:
- DispatcherServlet: 모든 HTTP 요청을 중앙에서 처리하는 Front Controller.
- Controller: 사용자 요청을 처리하고 모델 데이터를 생성하는 역할을 한다.
- Model: 데이터와 비즈니스 로직을 포함하며, 뷰에 전달될 데이터를 보유한다.
- View: 모델 데이터를 기반으로 사용자에게 응답을 렌더링한다. JSP, Thymeleaf 등이 사용될 수 있다.
모든 클라이언트 요청은 DispatcherServlet으로 들어오며, 여기서 요청을 적절한 Controller로 라우팅하고, 응답을 생성하여 클라이언트에 반환한다.
Spring Web MVC의 동작 과정
서블릿 처리 과정
이 이미지에서는 서블릿의 기본적인 처리 과정을 도식화하고 있다. 기본적인 서블릿 API의 동작은 다음과 같다.
- 클라이언트 요청 (HTTP REQUEST): 클라이언트(예: 웹 브라우저)가 서버로 HTTP 요청을 보낸다.
- 컨테이너: 서블릿 컨테이너(Tomcat, Jetty 등)가 요청을 수신한다. 서블릿 컨테이너는 Java EE 웹 애플리케이션 서버의 일부분으로, 서블릿의 생명주기를 관리하고, HTTP 요청을 처리한다.
- HttpServletRequest 및 HttpServletResponse 객체 생성:컨테이너는 요청을 처리하기 위해 HttpServletRequest와 HttpServletResponse 객체를 생성한다. 이 객체들은 각각 클라이언트 요청과 서버 응답을 나타낸다.
- 서블릿 분석 및 매핑: 컨테이너는 `web.xml` 파일 또는 어노테이션을 사용하여 요청 URL과 서블릿 클래스를 매핑한다.
- service() 메서드 호출: 컨테이너는 HttpServletRequest와 HttpServletResponse 객체를 인자로 전달하여 서블릿의 `service()` 메서드를 호출한다. `service()` 메서드는 HTTP 요청의 메서드 타입(GET, POST 등)에 따라 `doGet()`, `doPost()` 등의 메서드를 호출한다.
- doGet(), doPost() 메서드 처리: 서블릿은 `doGet()`이나 `doPost()` 메서드에서 클라이언트의 요청을 처리하고, 필요한 로직을 수행한다. 처리 결과는 HttpServletResponse 객체에 담아 클라이언트에게 반환된다.
- 클라이언트 응답 (HTTP RESPONSE): 서블릿의 처리 결과가 클라이언트로 HTTP 응답으로 전송된다.
아래 코드는 HttpServlet을 상속하여 서블릿을 구현한 예제이다.
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
// 응답 콘텐츠 유형 설정
response.setContentType("text/html");
// 응답 출력 스트림 준비
PrintWriter out = response.getWriter();
// HTML 응답 작성
out.println("<html><body>");
out.println("<h1>Hello, World!</h1>");
out.println("</body></html>");
}
}
DispatcherServlet
Spring Web MVC에서는 요청의 종류마다 서블릿 클래스를 생성해야 하는 문제를 해결하기 위해 DispatcherServlet이 사용된다. DispatcherServlet은 Front Controller 패턴을 구현하여 모든 요청을 중앙에서 처리한다. 이를 통해 각 요청마다 서블릿 클래스를 생성할 필요 없이, 중앙에서 공통된 로직을 처리할 수 있다.
Front Controller
Front Controller 패턴은 웹 애플리케이션의 중앙 진입점을 제공하여 모든 요청을 한 곳에서 처리하는 디자인 패턴이다. 이 패턴은 공통 기능(인증, 로깅, 오류 처리 등)을 중앙에서 처리할 수 있도록 하여 코드 중복을 줄이고, 요청 처리를 단순화한다.
DispatcherServlet의 동작 과정
- 요청 수신: 클라이언트의 요청이 서블릿 컨테이너를 통해 DispatcherServlet으로 전달된다.
- 핸들러 매핑: DispatcherServlet은 핸들러 매핑을 통해 요청을 처리할 컨트롤러를 찾는다.
- 핸들러 어댑터: 컨트롤러를 호출하기 위해 핸들러 어댑터를 사용한다.
- 비즈니스 로직 수행: 컨트롤러는 적절한 메서드를 호출하여 Model, 또는 View를 반환하기 위한 비즈니스 로직을 수행한다.
- 뷰 리졸버: 컨트롤러가 반환한 논리적 뷰 이름을 실제 뷰로 변환한다.
- 뷰 렌더링: 모델 데이터를 뷰에 적용하여 최종 응답을 생성한다.
- 응답 반환: 생성된 응답을 클라이언트에게 반환한다.
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class HelloController {
@GetMapping("/hello")
@ResponseBody
public String hello() {
return "<html><body><h1>Hello, World!</h1></body></html>";
}
}
Spring MVC에서는 서블릿을 직접 작성하는 대신, 위와 같이 @Controller 어노테이션을 사용하여 컨트롤러를 정의하고, DispatcherServlet이 이를 처리하도록 한다. @Controller, @RestController, @GetMapping, @ResponseBody 등의 어노테이션을 사용하여 HTTP 요청을 처리하고 응답을 반환하는 방식은 전통적인 서블릿 작성 방식보다 훨씬 간단하고 효율적이다.
참고
- 스파르타 코딩교육 - Spring Master 1주차 강의 노트
'Development > Spring' 카테고리의 다른 글
[Spring] HttpSession과 Session Clustering (0) | 2024.08.06 |
---|---|
[Spring] MSA와 Spring Cloud (1) | 2024.07.31 |
[Spring] 서버 모니터링을 위한 Spring Actuator, Prometheus, Grafana 추가하기 (0) | 2024.07.12 |
[Spring] Redisson을 활용한 캐시 사용하기 (0) | 2024.07.11 |
[Spring] Gatling 으로 서버 부하 테스트하기 (0) | 2024.07.09 |