cs log

Spring Dispatcher Servlet의 작동방식

· cs

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
}

각 코드별로 하는 역할을 정리하면 다음과 같다.

  1. Spring Application Context 생성
  2. Application Context에 Spring bean 설정 정보를 가진 클래스를 등록
  3. HttpServlet의 구현체인 Dispatcher Servlet 에 Spring Application Context를 주입한다.
  4. Dispathcer Servlet을 Servlet Container에 등록한다.
  5. 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맞게 호출해준다.