공부를 해보다가 메인클래스가 왜 SpringBootServletInitializer를 상속하고 있는 형태였다. 이것은 무엇이고 왜 상속받고 있는지 궁금해서 공부해 보았습니다.
@SpringBootApplication
@EnableJpaAuditing
public class PostsServiceApplication extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(PostsServiceApplication.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(PostsServiceApplication.class);
}
}
SpringBootServletInitalizer란 무엇이고 왜 상속받고 있는가?
- SpringBoot 웹 애플리케이션을 배포할 때는 주로 embedded tomcat이 내장된 jar 파일을 이용합니다.
- 하지만 특별한 경우에는 전통적인 배포 방식인 war 파일로 배포를 진행해야 경우가 있을 수 있습니다.
- 이럴경우에 SpringBootServletInitalizer를 상속 받으면 됩니다.
- 즉, war 파일로 빌드하고 배포하지 않을 거라면 SpringBootServletInitalizer를 상속할 필요가 없습니다.
그렇다면 왜 SpringBoot 웹 애플리케이션을 war로 배포할 때 SpringBootServletInitalizer를 상속 해야할까?
- Spring 웹 애플리케이션을 외부 Tomcat에서 동작하도록 하기 위해서는 web.xml (Deployment Descriptor, DD)에 애플리케이션 컨텍스트를 등록해야만 한다. 이는, Apache Tomcat(Servlet Container)이 구동될 때 /WEB-INF 디렉토리에 존재하는 web.xml을 읽어 웹 애플리케이션을 구성하기 때문이다.
- 지만 Servlet 3.0 스펙으로 업데이트되면서 web.xml이 없어도 동작이 가능해졌다. 이는, web.xml 설정을 WebApplicationInitializer인터페이스를 구현하여 대신할 수 있게 됐고, 프로그래밍적으로 ServletContext에 Spring IoC 컨테이너(AnnotationConfigWebApplicationContext)를 생성하여 추가할 수 있도록 변경됐기 때문이다.
- 이와 비슷한 맥락에서, web.xml이 없는 SpringBoot 웹 애플리케이션을 외부 Tomcat에서 동작하도록 하기 위해서는 WebApplicationInitializer 인터페이스를 구현한 SpringBootServletInitializer를 상속을 받는 것이 필요했던 것이다.