
마이크로서비스 아키텍처(MSA)에서 스프링 웹 MVC 프레임워크는 웹 애플리케이션을 구축하는 데 중요한 역할을 합니다.
이 프레임워크는 J2EE 스펙 중 Servlet을 기반으로 하며, MVC 패턴을 통해 애플리케이션의 구조를 명확하게 정의합니다. 이번 포스트에서는 스프링 웹 MVC 프레임워크의 주요 구성 요소와 동작 방식에 대해 살펴보겠습니다.
HTTP 프로토콜과 Servlet
Servlet
Servlet은 HTTP 프로토콜을 사용하여 클라이언트와 서버 간의 데이터를 주고받는 서버용 프로그래밍 스펙을 제공합니다. Servlet의 주요 버전별 특징은 다음과 같습니다:
- 서블릿 3.0: 비동기 서블릿 기능을 지원합니다
- 서블릿 3.1: 비차단 방식의 IO 기능을 지원합니다
- 서블릿 4.0: HTTP/2.0 기반의 기능을 지원합니다
- 서블릿 5.0 (2025년 최신): HTTP/3 지원 및 가상 스레드 최적화
Servlet 애플리케이션 내부에서는 HttpServletRequest와 HttpServletResponse를 통해 클라이언트와 서버 간의 통신을 처리합니다.
@WebServlet("/hello")
public class HelloServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 요청 처리
String name = request.getParameter("name");
// 응답 생성
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
out.println("Hello, " + name + "!");
}
}MVC 패턴 기반 프레임워크
스프링 웹 MVC 프레임워크는 MVC(모델-뷰-컨트롤러) 패턴을 기반으로 하여 웹 애플리케이션의 구조를 명확히 하고, 각 구성 요소의 역할을 분리하여 관리합니다.
애플리케이션 구조
스프링 MVC는 다음과 같은 세 가지 주요 구성 요소로 나뉩니다:
모델 (Model)
- 요청 데이터를 가공하거나, 저장소에서 데이터를 처리하는 역할을 합니다
- 비즈니스 로직을 처리하며, 컨트롤러와 뷰 간의 데이터 교환을 담당합니다
뷰 (View)
- 사용자에게 응답하는 화면을 담당하며, 모델 데이터를 HTML, JSON, XML 등의 형식으로 생성합니다
- 최종 사용자에게 보여줄 정보를 구성합니다
컨트롤러 (Controller)
- 사용자 요청을 받아 어떻게 처리할지 결정하는 역할을 합니다
- 요청을 분석하고, 적절한 서비스 메소드로 전달하여 결과를 반환합니다
// Model
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
private String email;
// getters, setters...
}
// Controller
@RestController
@RequestMapping("/api/users")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
public ResponseEntity getUser(@PathVariable Long id) {
User user = userService.findById(id);
return ResponseEntity.ok(user);
}
@PostMapping
public ResponseEntity createUser(@RequestBody User user) {
User savedUser = userService.save(user);
return ResponseEntity.status(HttpStatus.CREATED).body(savedUser);
}
}
// View (JSON 응답)
{
"id": 1,
"name": "John Doe",
"email": "john@example.com"
}의존성 관리
각 구성 요소 간의 의존성이 발생하므로, 스프링은 제어의 역전(IoC) 컨테이너를 제공합니다. 이를 통해 빈의 생명주기 및 의존 관계를 관리하여 객체 간의 결합도를 낮추고, 애플리케이션의 구조를 더욱 유연하게 만듭니다.
동작 순서
스프링 MVC의 핵심 동작 순서는 다음과 같습니다:
- 요청 처리: 사용자의 모든 HTTP 요청은 DispatcherServlet이 우선적으로 처리합니다
- 컨트롤러 선택: HTTP 요청라인(URL)에 따라 어떤 컨트롤러가 요청을 처리할지를 판단합니다
- 서비스 메소드 호출: 선택된 컨트롤러는 서비스 기능을 구현한 메소드를 호출하여 결과를 리턴합니다
- ModelAndView 객체 생성: 컨트롤러는 ModelAndView 객체를 통해 UI를 처리할 수 있는 뷰를 찾아 리턴된 데이터를 전달합니다
- 뷰 처리: 뷰는 전달받은 데이터를 매핑하여 DispatcherServlet에 전달합니다
DispatcherServlet
DispatcherServlet은 스프링 MVC 프레임워크에서 프런트 컨트롤러 패턴으로 디자인된 핵심 구성 요소입니다. 이 객체는 모든 HTTP 요청을 중앙에서 관리하며, 각 요청을 적절한 컨트롤러로 전달하고 응답을 처리하는 역할을 합니다.
프런트 컨트롤러 패턴
DispatcherServlet은 프런트 컨트롤러 패턴을 기반으로 하여 모든 요청을 단일 진입점으로 처리합니다. 이 패턴의 장점은 요청 처리 로직을 중앙집중화하여 관리할 수 있다는 점입니다.
주요 컴포넌트
HandlerMapping
- 역할: 사용자의 HTTP 요청 메시지를 추상화한 HttpServletRequest 객체를 받아, 요청을 처리할 핸들러 객체를 조회합니다
- 기능: @RequestMapping 어노테이션을 로딩하여 URL과 핸들러의 매핑 정보를 관리합니다
HandlerAdapter
- 역할: 사용자의 요청과 응답을 추상화한 HttpServletRequest와 HttpServletResponse 객체를 컨트롤러 클래스의 메소드에 전달합니다
- 기능: 요청을 처리하고 결과를 반환하는 메소드를 호출하여, ModelAndView 객체를 리턴합니다
ModelAndView
- 역할: 처리된 결과를 뷰와 데이터로 전달하는 클래스입니다
- 기능: 모델 데이터와 뷰 이름을 함께 저장하여, 뷰가 어떻게 데이터를 표시해야 하는지를 명시합니다
ViewResolver
- 역할: 문자열 기반 뷰 이름을 실제 뷰 구현체로 변경하는 역할을 합니다
- 기능: ModelAndView 객체에서 전달받은 뷰 이름을 바탕으로 해당 뷰를 찾아 반환합니다
// DispatcherServlet 설정 예시
@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix("/WEB-INF/views/");
resolver.setSuffix(".jsp");
return resolver;
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
}스프링 시큐리티와의 통합
DispatcherServlet의 프런트 컨트롤러 기능 덕분에 스프링 시큐리티 프레임워크를 애플리케이션에 쉽게 적용할 수 있습니다. 모든 요청이 DispatcherServlet을 통해 처리되므로, 보안 필터를 중앙에서 관리하고, 인증 및 인가 로직을 통합하는 데 용이합니다.
서블릿 스택과 스레드 모델
서블릿 스택과 리액티브 스택은 웹 애플리케이션의 요청 처리 방식에 따라 다르게 동작합니다. 각각의 스택은 프로그래밍 모델, 스레드 관리, 요청 처리 방식에서 중요한 차이를 보입니다.
서블릿 스택
동기 방식 프로그래밍
- 서블릿 스택은 동기 방식으로 프로그래밍됩니다
- 요청이 들어오면 해당 요청을 처리하는 스레드가 생성되고, 모든 작업이 순차적으로 처리됩니다
스레드 관리
- 하나의 기능을 하나의 스레드에서만 동작: 각 요청은 별도의 스레드에서 처리되며, 하나의 스레드가 하나의 요청을 전담합니다
- 비교적 쉬운 프로그래밍: 동기 방식으로 인해 코드가 직관적이며, 요청의 흐름을 추적하기가 용이합니다
서블릿 스택 애플리케이션 특징
- 스레드 풀: WAS(Web Application Server)는 스레드 관리를 위해 스레드 풀을 포함하고 있습니다
- 요청-응답 생명주기: 사용자 요청부터 응답까지 모든 작업은 하나의 스레드에서 실행됩니다
- 디버깅 용이성: 스레드를 직접 다루지 않기 때문에 로그 확인과 디버깅이 비교적 쉬워집니다
리액티브 스택
비동기 방식 프로그래밍
- 리액티브 스택은 비동기 방식으로 프로그래밍됩니다
- 요청 처리가 완료될 때까지 기다리지 않고, 다른 작업을 병행하여 수행할 수 있습니다
이벤트 루프
- 콜백 함수 호출: 실행한 메소드가 종료되면 전달된 콜백 함수를 호출합니다
- 다중 스레드 사용: 하나의 기능이 여러 스레드에 걸쳐서 수행될 수 있습니다
| 프로그래밍 방식 | 동기 방식 | 비동기 방식 |
| 스레드 모델 | 요청당 스레드 | 이벤트 루프 |
| 개발 복잡도 | 단순 | 복잡 |
| 성능 | 중간 | 높음 |
| 디버깅 | 용이 | 어려움 |
스프링 부트 설정
스프링 부트는 웹 애플리케이션을 빠르고 간편하게 개발할 수 있도록 돕는 프레임워크입니다. 스프링 부트를 사용하여 웹 애플리케이션을 설정하기 위해 필요한 설정들을 살펴보겠습니다.
pom.xml 설정
스프링 부트를 사용하여 웹 애플리케이션을 개발하기 위해서는 pom.xml 파일에 spring-boot-starter-web 의존성을 추가해야 합니다.
4.0.0
org.springframework.boot
spring-boot-starter-parent
3.2.0
com.example
my-web-app
1.0.0
jar
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-security
org.springframework.boot
spring-boot-maven-plugin
application.properties 설정
application.properties 파일은 스프링 부트 애플리케이션의 설정을 관리하는 파일입니다. 2025년 최신 설정 예시는 다음과 같습니다:
# 서버 설정
server.port=8080
server.servlet.context-path=/api
# 톰캣 설정
server.tomcat.connection-timeout=30s
server.tomcat.threads.max=200
server.tomcat.threads.min-spare=10
server.tomcat.max-connections=8192
# 접근 로그 설정
server.tomcat.accesslog.enabled=true
server.tomcat.accesslog.suffix=.log
server.tomcat.accesslog.prefix=access_log
server.tomcat.accesslog.rename-on-rotate=true
# JPA 설정
spring.jpa.hibernate.ddl-auto=validate
spring.jpa.show-sql=false
spring.jpa.properties.hibernate.format_sql=true
# 데이터베이스 설정
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 로깅 설정
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate.SQL=DEBUG
logging.pattern.console=%d{yyyy-MM-dd HH:mm:ss} - %msg%n
# 프로파일별 설정
spring.profiles.active=devYAML 설정 (application.yml)
server:
port: 8080
servlet:
context-path: /api
tomcat:
connection-timeout: 30s
threads:
max: 200
min-spare: 10
max-connections: 8192
spring:
application:
name: my-web-app
datasource:
url: jdbc:mysql://localhost:3306/mydb
username: root
password: password
driver-class-name: com.mysql.cj.jdbc.Driver
jpa:
hibernate:
ddl-auto: validate
show-sql: false
properties:
hibernate:
format_sql: true
logging:
level:
org.springframework.web: DEBUG
org.hibernate.SQL: DEBUG
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss} - %msg%n"마무리
스프링 웹 MVC 프레임워크는 MSA에서 웹 애플리케이션을 구축하는 데 필요한 강력한 도구입니다. MVC 패턴을 통해 애플리케이션 구조를 명확히 하고, DispatcherServlet을 통해 모든 요청을 중앙에서 관리함으로써 개발의 효율성을 높입니다.
핵심 포인트:
- MVC 패턴을 통한 명확한 역할 분리로 유지보수성 향상
- DispatcherServlet의 프런트 컨트롤러 패턴으로 중앙집중식 요청 처리
- 서블릿 스택과 리액티브 스택의 특성 이해를 통한 적절한 아키텍처 선택
- Spring Boot의 자동 설정을 활용한 빠른 개발 환경 구축
잠깐 소개된 리액티브 스택, WebFlux, Reactor 등에 대해서도 추후 자료 공유하겠습니다. 2025년 현재 Spring Framework 7.0과 Spring Boot 3.x 버전의 최신 기능들을 활용하여 더욱 효율적인 웹 애플리케이션을 개발할 수 있습니다.
'IT기술 > MSA (with. springboot)' 카테고리의 다른 글
| Spring Boot GET/DELETE API 매핑 완벽 가이드: MSA 환경에서의 호텔 관리 시스템 구현 (2) | 2025.07.09 |
|---|---|
| REST API 완벽 가이드: MSA 환경에서의 효율적인 서비스 간 통신 설계 (0) | 2025.07.09 |
| Spring Boot DTO 패턴 완벽 가이드: MSA 환경에서의 효율적인 데이터 전송 객체 활용 (2) | 2025.07.07 |
| Spring Bean, Java Bean, DTO, VO와 불변 클래스 설계 완벽 가이드: MSA 환경에서의 객체 관리 전략 (0) | 2025.07.07 |
| Spring @Primary와 @Lazy 어노테이션 완벽 가이드: MSA 환경에서의 효율적인 빈 관리 (0) | 2025.07.06 |