스프링부트 동작방식
스프링 부트에서 spring-boot-starter-web 모듈을 사용하면 기본적으로 톰캣(Tomcat)을 사용하는 스프링 MVC 구조를 기반으로 동작합니다. 아래는 일반적인 웹 요청이 들어왔을 때의 스프링 부트의 동작 구조입니다.
서블릿(Servlet)은 클라이언트의 요청을 처리하고 결과를 반환하는 자바 웹 프로그래밍 기술입니다. 일반적으로 서블릿은 서블릿 컨테이너(Servlet Container)에서 관리합니다. 서블릿 컨테이너는 서블릿 인스턴스(Servlet Instance)를 생성하고 관리하는 역할을 수행하는 주체로서 톰캣은 WAS의 역할과 서블릿 컨테이너의 역할을 수행하는 대표적인 컨테이너입니다. 서블릿 컨테이너의 특징은 다음과 같습니다.
- 서블릿 객체를 생성, 초기화, 호출, 종료하는 생명주기를 관리합니다.
- 서블릿 객체는 싱글톤 패턴으로 관리됩니다.
- 멀티 스레딩을 지원합니다.
스프링에서는 DispatcherServlet이 서블릿의 역할을 수행합니다. 일반적으로 스프링은 톰캣을 임베드(embed)해 사용합니다. 그렇기 때문에 서블릿 컨테이너와 DispatcherServlet 은 자동 설정된 web.xml의 설정값을 공유합니다.
위 그림에서 나온 DispatcherServlet의 동작을 간략히 살펴보겠습니다.
(1) DispatcherServlet으로 요청(HttpServletRequest)이 들어오면 DispatcherServlet은 핸들러 매핑(Handler Mapping)을 통해 요청 URI에 매핑된 핸들러를 탐색합니다. 여기서 핸들러는 컨트롤러(Controller)를 의미합니다.
(2) 핸들러 어댑터로 컨트롤러를 호출합니다.
(3) 핸들러 어댑터에 컨트롤러의 응답이 돌아오면 ModelAndView로 응답을 가공해 반환합니다.
(4) 뷰 형식으로 리턴하는 컨트롤러를 사용할 때는 뷰 리졸버(View Resolver)를 통해 뷰(View)를 받아 리턴합니다.
핸들러 매핑은 요청 정보를 기준으로 어떤 컨트롤러를 사용할지 선정하는 인터페이스입니다. 핸들러 매핑 인터페이스는 여러 구현체를 가지며, 대표적인 구현체 클래스는 다음과 같습니다.
BeanNameUrlHandlerMapping
- 빈 이름을 URL로 사용하는 매핑 전략입니다.
- 빈을 정의할 때 슬래시('/')가 들어가면 매핑 대상이 됩니다.
- 예) @Bean("/hello")
ContorllerClassNameHandlerMapping
- URL과 일치하는 클래스 이름을 갖는 빈을 컨트롤러로 사용하는 전략입니다.
- 이름 중 Controller를 제외하고 앞부분에 작성된 suffix를 소문자로 매핑합니다.
SimpleUrlHandlerMapping
- URL 패턴에 매핑된 컨트롤러를 사용하는 전략입니다.
DefaultAnnotationHandlerMapping
- 어노테이션으로 URL과 컨트롤러를 매핑하는 방법입니다.
뷰 리졸버는 뷰의 렌더링 역할을 담당하는 뷰 객체를 반환합니다.
뷰가 없는 REST 형식의 @ResponseBody를 사용할 경우 아래와 같이 뷰 리졸버를 호출하지 않고 MessageConverter를 걸쳐 JSON 형식으로 변환해서 응답합니다.
여기서 MessageConverter는 요청과 응답에 대해 Body 값을 변환하는 역할을 수행합니다. 스프링 부트의 자동 설정 내욕을 보면 HttpMessageConverter 인터페이스를 사용하고 있습니다.
아래는 spring.factories에 정의된 HttpMessageConvertrersAutoConfiguration 클래스입니다.
@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(HttpMessageConverter.class)
@Conditional(NotReactiveWebApplicationCondition.class)
@AutoConfigureAfter({ GsonAutoConfiguration.class, JacksonAutoConfiguration.class,
JsonbAutoConfiguration.class})
@Import({ JacksonHttpMessageConvertersConfiguration.class, GsonHttpMessageConvertersConfiguration.class,
JsonbHttpMessageConvertersConfiguration.class })
public class HttpMessageConvertersAutoConfiguration{
static final String PREFERRED_MAPPER_PROPERTY = "spring.mvc.converts.preferred-json-mapper";
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters){
return new HttpMessageConvertes(converters.orderedStream().collect(Collectors.toList()));
}
...생략...
}
2번 라인을 보면 HttpMessageConverter 인터페이스를 빈으로 등록하는 것을 볼 수 있습니다. 해당 인터페이스를 기반으로 하는 구현체 클래스는 다양하며, Content-Type을 참고해서 Converter를 선정합니다. 스프링 부트에서는 자동 설정되기 때문에 별도 설정이 필요하지 않습니다.
'웹 개발 > 🍃 SpringBoot' 카테고리의 다른 글
Language - spring initializr 정복하기(2) (0) | 2024.12.17 |
---|---|
Project - spring initializr 정복하기(1) (0) | 2024.12.17 |
REST API (0) | 2024.10.23 |
Spring | HandlerInterceptor를 이용한 로그인구현 (0) | 2024.03.15 |
Lombok VO 변수명 설정시 유의사항 (0) | 2024.03.08 |