본문 바로가기
  • 실행력이 모든걸 결정한다
Spring Series/Spring Framework

[Spring] web.xml 대신에 WebApplicationInitializer 사용하기

by 김코더 김주역 2022. 9. 7.
반응형

1. WebApplicationInitializer 소개

- Spring 3.1의 새로운 기능으로, 서블릿 3.0 환경 이상에서 사용 가능하다.

<!-- web.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee https://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">

- web.xml에서 다루는 주요 설정 방식을 모듈화 해서 관리할 때 사용된다. web.xml 내에서 <listener>나 <servlet>을 이용해 등록했던 루트 컨텍스트나 서블릿 컨텍스트를 자바 코드에서 직접 등록하고 생성할 수 있다.

- ServletContainerInitializer은 WebApplicationInitializer의 구현체를 찾아 컨텍스트의 초기화 작업을 위임한다. Spring의 웹 모듈 내에는 ServletContainerInitializer의 구현체가 포함되어 있다.

public interface WebApplicationInitializer {
    void onStartup(ServletContext servletContext) throws ServletException;
}

 

 

 

2. 루트 컨텍스트 등록

1) 리스너로 등록

- web.xml에서는 <listener>를 이용해서 루트 컨텍스트를 등록했다. 그러면 기본적으로 XmlWebApplicationContext 타입의 애플리케이션 컨텍스트가 생성되어 서블릿 컨텍스트의 초기화 이벤트와 종료 이벤트를 전달받게 된다. 참고로, 루트 컨텍스트를 리스너로 관리해야 서블릿 컨텍스트의 종료 이벤트를 받았을 때 리소스를 적절히 반환할 수 있다.

<listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

자바 코드로 위의 설정을 수행한 내용은 다음과 같다.

ServletContextListener listener = new ContextLoaderListener();
servletContext.addListener(listener);

ContextLoaderListener의 생성자에 아무 파라미터도 넣지 않으면 등록된 컨텍스트 파라미터가 있는지 확인하고, 없으면 디폴트 설정을 가진 루트 컨텍스트를 만든다.

 

 

2) 컨텍스트 클래스와 기본 설정 파일 등록

- web.xml에서는 컨텍스트 파라미터의 contextClass 속성을 이용해서 컨텍스트 클래스를 설정하고, contextConfigLocation 속성을 이용해서 기본 설정 파일을 등록했다.

<context-param>
    <param-name>contextClass</param-name>
    <param-value>org.springframework.web.context.support.AnnotationConfigWebApplicationContext</param-value>
</context-param>

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>[클래스 또는 패키지]</param-value>
</context-param>

자바 코드로 1), 2)의 설정을 수행한 내용은 다음과 같다.

AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
servletContext.scan("[클래스 및 패키지]");

ServletContextListener listener = new ContextLoaderListener(ac);
servletContext.addListener(listener);

 

 

 

 

3. 서블릿 컨텍스트 등록

- web.xml에서는 <servlet>을 이용해서 서블릿 컨텍스트를 등록했다. 루트 컨텍스트는 리스너에서 관리되고 서블릿 컨텍스트는 서블릿에서 관리되는 것이다.

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/spring/appServlet/servlet-context.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>

자바 코드로 위의 설정을 수행한 내용은 다음과 같다.

XmlWebApplicationContext sac = new XmlWebApplicationContext();
sac.setConfigLocation("/WEB-INF/spring/appServlet/servlet-context.xml");

ServletRegistration.Dynamic dispatcher = servletContext.addServlet("appServlet", new DispatcherServlet(sac));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");

참고로, AnnotationConfigWebApplicationContext 타입의 애플리케이션 컨텍스트를 사용하고 싶다면 다음과 같이 등록할 수 있다.

AnnotationConfigWebApplicationContext sac = new AnnotationConfigWebApplicationContext();
sac.register(AppConfig.class); // 기본 설정 클래스 등록

ServletRegistration.Dynamic dispatcher = servletContext.addServlet("appServlet", new DispatcherServlet(sac));
...

- 서블릿 컨텍스트를 DispatcherServlet의 디폴트 설정과 다르게 적용하여 생성하는 경우에 web.xml에서는 <init-param>을 사용했는데, 자바 코드에서는 setInitParameter() 메소드를 이용하면 된다.

 

 

 

4. 정리

- 이렇게 루트 컨텍스트와 서블릿 컨텍스트를 등록하는 자바 코드를 WebApplicationInitializer의 구현체에 작성해두기만 하면 된다. 심지어 web.xml을 아예 없애도 된다.

 

 

● 참고 자료 : 토비의 스프링 3.1 Vol.2

 

 

반응형

댓글