Spring Boot 2 實戰:以 War 包的形式部署

  • 2019 年 12 月 9 日
  • 筆記

1. 前言

Spring Boot 提供了內置的 tomcat、undertow、jetty 三種 Servlet Web 容器。讓我們開箱即用,可以迅速以 JAR 啟動一個 Web 應用。但是在某些場景中我們可能還需要將我們的 Spring Boot 容器以 War 的形式進行傳統的部署。這時我們就需要通過藉助於 SpringBootServletInitializer 來實現。

2. SpringBootServletInitializer

SpringBootServletInitializer 是 WebApplicationInitializer 的實現,它從部署在 Web 容器上的傳統 WAR 包運行 Spring Boot 應用。該類將 Servlet,Filter 和 ServletContextInitializer Bean 從應用程式上下文綁定到伺服器。SpringBootServletInitializer 類還允許我們通過覆蓋 SpringApplicationBuilder configure(SpringApplicationBuilder application)方法來配置由 Servlet 容器運行的應用程式。

3. Spring Boot War 部署

接下來我們來講述詳細的 Spring Boot War 部署步驟。

3.1 修改打包方式為 War

修改 Spring Boot 項目的 pom.xml 文件將打包方式修改為 war 。

默認打 jar 包 <packaging>jar</packaging> 我們改為打 war 包 <packaging>war</packaging>

3.2 排除 內嵌的 Web 容器。

默認使用內嵌 Tomcat Web 容器。如果此前你使用了內嵌的 Jetty、Undertow ,請務必清除相關的 Starter 依賴。然後我們可以使用兩種方式來處理:

  • 方法一

Spring Boot 內嵌的Tomcat默認已經集成在spring-boot-starter-web包里,所以我們要排除掉它。

``` xml  <dependency>      <groupId>org.springframework.boot</groupId>      <artifactId>spring-boot-starter-web</artifactId>      <exclusions>          <exclusion>              <groupId>org.springframework.boot</groupId>              <artifactId>spring-boot-starter-tomcat</artifactId>          </exclusion>      </exclusions>  </dependency>  ```  此方式我們把 **Servlet Api** 依賴也排除掉了,  `SpringBootServletInitializer` 需要依賴 **Servlet Api** ,因此我們要加上它(**務必注意 versionNumber 版本要跟你外置的 Tomcat 版本兼容**)。  ``` xml  <dependency>      <groupId>javax.servlet</groupId>      <artifactId>javax.servlet-api</artifactId>      <version>${versionNumber}</version>      <scope>provided</scope>  </dependency>  ```
  • 方法二

我們通過引入 spring-boot-starter-tomcat 覆蓋掉默認的內置 Tomcat 並設置作用範圍(scope)是provided(編譯、測試)。

   ```xml   <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-tomcat</artifactId>       <scope>provided</scope>   </dependency>  ```

3.3 實現 SpringBootServletInitializer 介面

新建 SpringBootServletInitializer 的實現類 ServletInitializer 如下:

 package cn.felord.war;     import org.springframework.boot.builder.SpringApplicationBuilder;   import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;     /**    * @author Felordcn    */   public class ServletInitializer extends SpringBootServletInitializer {         @Override       protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {             return application.sources(WarSpringBootApplication.class);       }     }

其中 WarSpringBootApplication 是 Spring Boot 的入口類,跟原來沒什麼兩樣:

 package cn.felord.war;     import org.springframework.boot.SpringApplication;   import org.springframework.boot.autoconfigure.SpringBootApplication;     /**    * @author Felordcn    */   @SpringBootApplication   public class WarSpringBootApplication {         public static void main(String[] args) {           SpringApplication.run(WarSpringBootApplication.class, args);       }     }

3.4 編譯打包

通過 maven 命令 mvn clean package 執行編譯,稍等片刻,就會獲得 ${artifactId}-${version}.war ,然後你就可以以傳統的 War 部署方式運行 Spring Boot 應用了。

4. 總結

總體來說 War 部署 Spring Boot 的方式也並不複雜。

Tags: