본문 바로가기
스프링 (Spring)

[Spring boot] war로 배포하기, SpringBootServletInitalizer

by codeyaki 2023. 7. 22.
반응형

현재는 spring boot에 Tomcat이 내장되어 있는 Embedded Tomcat형태의 jar파일로 빌드되어 단순히 실행하면 되지만 jsp를 사용하는 웹애플리케이션 같은 경우에는 war로 빌드하여 Tomcat이나 Jetty와 같은 외부 서블릿 컨테이너를 통해서 배포를 해야 했는데 이경우에 SpringBootServletInitalizer를 상속받아서 실행되도록 하여야 한다.

즉, SpringBootServletInitalizer를 상속받는 이유는 웹 애플리케이션 서버를 war형태로 배포하기 위해서 사용한다.

jar vs war

그렇다면 war와 jar는 어떤 차이가 있는건지도 알아보았다. 먼저 두 파일 전부 애플리케이션을 간단하게 배포하고 실행시킬 수 있도록 관련파일들을 패키징 해주는 것이 목적이다. 

jar

  • Java 애플리케이션 및 라이브러리의 컴파일된 클래스 파일, 리소스 파일, 메타데이터 및 라이브러리들을 패키징 하는 데 사용
  • 주로 독립 실행형 응용 프로그램과 라이브러리를 패키징하는 데 사용
  • JVM을 통해서 실행한다. (JRE 필요)
  • META-INF 디렉터리 아래에 메타데이터와 리소스가 포함, 클래스 파일은 루트 디렉터리에 포함

war ( Web Application Archive)

  • WAR 파일은 Java 웹 애플리케이션을 패키징 하는 데 사용
  • 웹 애플리케이션은 HTML, CSS, JavaScript, JSP(JavaServer Pages), 서블릿 클래스, 리소스 파일 등을 포함한다.
  • 주로 웹 애플리케이션 서버(예: Apache Tomcat, Jetty, 등)에서 실행하는 데 사용.
    웹 애플리케이션 서버는 WAR 파일을 통해 웹 애플리케이션을 배포하고 실행한다.
  • WAR 파일은 웹 애플리케이션의 내용을 정의하는 규칙이 따로 있다.
    WEB-INF 디렉터리 아래에 웹 애플리케이션 설정, 서블릿 클래스, JSP 파일 및 리소스가 포함된다.

즉, jar은 단독을 실행, war는 톰캣과 같은 was/web서버가 필요하다.

스프링 부트를 war로 빌드하기

그렇다면 jsp 프로젝트를 war로 빌드하기 위해서는 어떻게 해야하는지 알아보는 시간을 가져보았다.

https://docs.spring.io/spring-boot/docs/current/reference/html/howto.html#howto.traditional-deployment.war를 살펴보면 3가지 과정을 통해 jsp 프로젝트를 war로 빌드할 수 있다고 안내해 준다

 

1. SpringBootServletInitializer 상속받기

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;

@SpringBootApplication
public class YourSpringBootApp extends SpringBootServletInitializer {
    
    public static void main(String[] args) {
        SpringApplication.run(YourSpringBootApp.class, args);
    }
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(YourSpringBootApp.class);
    }
}
  • Spring 웹 애플리케이션을 외부 Tomcat에서 동작하도록 하기 위해서는 web.xml (Deployment Descriptor, DD)에 애플리케이션 컨텍스트를 등록해야만 했다. 이는, Apache Tomcat(Servlet Container)이 구동될 때 /WEB-INF 디렉터리에 존재하는 web.xml을 읽어 웹 애플리케이션을 구성하기 때문이다.
  • Servlet 3.0이 되면서 web.xml이 없어도 동작이 가능해졌다. WebApplicationInitializer 인터페이스를 구현하여 web.xml 설정을 대신할 수 있게 됐고, 프로그래밍적으로 ServletContext에 Spring IoC 컨테이너(AnnotationConfigWebApplicationContext)를 생성하여 추가할 수 있도록 변경됐기 때문이다.
  • 이와 비슷한 맥락에서, web.xml이 없는 SpringBoot 웹 애플리케이션을 외부 Tomcat에서 동작하도록 하기 위해서는 WebApplicationInitializer 인터페이스를 구현한 SpringBootServletInitializer를 상속을 받는 것이 필요했던 것이다.

2. 빌드 구성 바꾸기

  • pom.xml
<packaging>war</packaging>
apply plugin: 'war'
 

3. tomcat 디펜던시 추가하기

  • pom.xml
<dependencies>
    <!-- ... -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <!-- ... -->
</dependencies>
  • gradle.build
dependencies {
    // ...
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
    // ...
}

 

이렇게 해주면 이제 jsp 프로젝트를 war로 배포할 수 있게 된다.

거기에 인텔리제이에서 jsp를 인식하여 동작하기 시작하여 아주 좋다

반응형