Spring Dispatcher Servlet의 작동방식
Spring Container 와 Dispatcher Servlet
Spring 에서는 Dispatcher Servlet 을 Servlet Container에 등록해서 요청을 처리한다.
- servlet 이란 TCP/IP 연결, HTTP Message 파싱 , 응답 등 개발자가 HTTP 스펙을 매우 편리하게 사용할 수 있도록 웹 요청, 웹 응답 객체를 제공해주는 자바 서버측 표준 클래스
- servlet container란 WAS 안에서 servlet 생명주기(생성/초기화/호출/종료) 관리. 기본적으로 싱글톤으로 관리된다.
servlet에서는 ServletContainerIntializer라는 servlet container 초기화 인터페이스를 제공해준다.
package javax.servlet;
import java.util.Set;
public interface ServletContainerInitializer {
void onStartup(Set<Class<?>> var1, ServletContext var2) throws ServletException;
}
spring에서는 이 servlet container 초기화 메소드를 통해서 spring container를 생성하고, 등록하는 작업을 수행한다.
@Override
public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext applicationContext = new AnnotationConfigWebApplicationContext(); //1
applicationContext.register(/*빈 설정클래스*/); //2
// spring mvc dispatcher servlet 생성 : spring application context를 주입받는다.
DispatcherServlet dispatcher = new DispatcherServlet(applicationContext); //3
ServletRegistration.Dynamic servlet = servletContext.addServlet("dispatcherServlet", dispatcher); //4
servlet.addMapping("/*"); //5
}
각 코드별로 하는 역할을 정리하면 다음과 같다.
- Spring Application Context 생성
- Application Context에 Spring bean 설정 정보를 가진 클래스를 등록
- HttpServlet의 구현체인 Dispatcher Servlet 에 Spring Application Context를 주입한다.
- Dispathcer Servlet을 Servlet Container에 등록한다.
- Dispatcher Servlet이 받을 URL 경로를 매핑한다.
Dispatcher Servlet에 HTTP 요청이 들어오면 Spring Container에 들어있는 Controller Bean중에서 URL을 보고 적합한 Bean을 골라 호출한다. ( Spring의 Dispatcher Servlet은 Front Controller Design Pattern을 따른다)
WebApplicationInitializer
클래스를 사용하면 조금 더 편리하게 servlet 초기화 코드를 작성할 수 있다.
import org.springframework.web.WebApplicationInitializer;
public class SpringMvcServletInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
}
}
기존 ServletContainerInitializer
클래스의 경우는 /META-INF/services/jakarta.servlet.ServletContainerInitializer
라는 파일명으로 서블릿 컨테이너 초기화 로직이 들어 있는 클래스명을 지정해준다.
spring 에서 제공해주는 WebApplicationInitializer
클래스의 경우에도 내부적으로는 동일한 로직을 가지고 있다.
똑같이 /META-INF/services/jakarta.servlet.ServletContainerInitializer
경로에 서블릿 컨테이너 초기화 로직이 들어 있는 클래스명을 지정해주는데,
WebApplicationInitializer
의 구현체인 SpringBootServletInitializer
가 해당 파일에 적혀있다. 즉 SpringBootServletInitializer
클래스가 사용자[개발자]가 구현한 WebApplicationInitializer 를 호출해준다.
import org.springframework.web.context.WebApplicationContext;
public abstract class SpringBootServletInitializer implements WebApplicationInitializer {
//
}
정리
-
Servlet Container는 Dispatcher Servlet이라는 Spring Application Context에 대한 참조값을 가지고 있는 Servlet 객체를 초기화 시점에 등록한다.
-
등록된 Dispather Servlet은 일종의 Front Controller로서 동작한다.
-
Spring Container 는 Dispatcher Servlet을 통해서 Application Context에 등록되어는 Controller를 사용자의 HTTP Request맞게 호출해준다.