spring boot:以 War 包的形式部署

1. 前言

Spring Boot 提供了内置的 tomcat、undertow、jetty 三种 Servlet Web 容器。让我们开箱即用,可以迅速以 JAR 启动一个 Web 应用。但是在某些场景中我们可能还需要将我们的 Spring Boot 容器以 War 的形式进行传统的部署。这时我们就需要通过借助于 SpringBootServletInitializer 来实现。

2. SpringBootServletInitializer

SpringBootServletInitializer 是 WebApplicationInitializer 的实现,它从部署在 Web 容器上的传统 WAR 包运行 Spring Boot 应用。该类将 ServletFilterServletContextInitializer Bean 从应用程序上下文绑定到服务器。SpringBootServletInitializer 类还允许我们通过覆盖 SpringApplicationBuilder configure(SpringApplicationBuilder application)方法来配置由 Servlet 容器运行的应用程序。

3. Spring Boot War 部署

3.1 排除 内嵌的 Web 容器。

默认使用内嵌 Tomcat Web 容器。如果此前你使用了内嵌的 JettyUndertow ,请务必清除相关的 Starter 依赖。然后我们可以使用两种方式来处理:

  • 方法一

Spring Boot 内嵌的Tomcat默认已经集成在spring-boot-starter-web包里,所以我们要排除掉它。

<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 版本兼容)。

<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <version>${versionNumber}</version>
    <scope>provided</scope>
</dependency>
  • 方法二

我们通过引入 spring-boot-starter-tomcat 覆盖掉默认的内置 Tomcat 并设置作用范围(scope)是provided(编译、测试)。

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

3.2 实现 SpringBootServletInitializer 接口

新建 SpringBootServletInitializer 的实现类 ServletInitializer 如下:

package org.ihoree.demo.springbootprovider;
 
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.servlet.support.SpringBootServletInitializer;
 
 /**
  * 挂载外部的servlet
  */
public class ServletInitializer extends SpringBootServletInitializer {
 
     @Override
     protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
 
         return application.sources(SpringbootWarApplication.class);
     }

}

其中 WarSpringBootApplication 是 Spring Boot 的入口类,跟原来没什么两样:

package org.ihoree.demo.springbootprovider;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * 以WAR包形式发布
 */
@SpringBootApplication
public class SpringbootWarApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringbootWarApplication.class, args);
    }

}

3.4 编译打包

修改pom.xml

<packaging>jar</packaging>
<packaging>war</packaging>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <!-- 加入maven deploy插件,当在deploy时,忽略些model-->
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-deploy-plugin</artifactId>
                <version>2.8.2</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>

通过 maven 命令 mvn clean package 执行编译,稍等片刻,就会获得 ${artifactId}-${version}.war ,然后你就可以以传统的 War 部署方式运行 Spring Boot 应用了。

关于Zeno Chen

本人涉及的领域较多,杂而不精 程序设计语言: Perl, Java, PHP, Python; 数据库系统: MySQL,Oracle; 偶尔做做电路板的开发,主攻STM32单片机
此条目发表在Java分类目录。将固定链接加入收藏夹。