java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > SpringBoot JAR和WAR方式打包部署

SpringBoot JAR和WAR方式打包并部署的详细步骤及对比分析

作者:悟空码字

无论选择JAR还是WAR部署方式,关键在于匹配团队的技术栈、运维能力和业务需求,Spring Boot的灵活性支持两种部署模式,为不同场景提供了合适的解决方案,本文给大家详细对比分析了这两种方式,需要的朋友可以参考下

一、JAR 和 WAR 打包的区别

JAR (Java ARchive)

WAR (Web Application ARchive)

二、详细打包部署步骤

项目结构

my-springboot-app/
├── src/
│   └── main/
│       ├── java/com/example/
│       └── resources/
└── pom.xml 或 build.gradle

1. 打包为可执行JAR(默认方式)

Maven 配置 (pom.xml)

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.example</groupId>
    <artifactId>my-springboot-app</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>  <!-- 打包为JAR -->
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.5</version>
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
    
    <build>
        <plugins>
            <!-- Spring Boot Maven 插件 -->
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <mainClass>com.example.MyApplication</mainClass>
                </configuration>
                <executions>
                    <execution>
                        <goals>
                            <goal>repackage</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
</project>

Gradle 配置 (build.gradle)

plugins {
    id 'org.springframework.boot' version '3.1.5'
    id 'io.spring.dependency-management' version '1.1.3'
    id 'java'
}

group = 'com.example'
version = '1.0.0'
sourceCompatibility = '17'

jar {
    enabled = true
    archiveClassifier = ''  // 移除plain后缀
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
}

// 可执行JAR配置
bootJar {
    mainClass = 'com.example.MyApplication'
    archiveClassifier = ''
}

主启动类

package com.example;

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

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

打包命令

# Maven
mvn clean package

# Gradle
./gradlew clean build

运行JAR

# 直接运行
java -jar target/my-springboot-app-1.0.0.jar

# 指定配置文件
java -jar target/my-springboot-app-1.0.0.jar \
  --spring.config.location=classpath:/,file:./config/

# 指定端口
java -jar target/my-springboot-app-1.0.0.jar \
  --server.port=8081

# 生产环境运行(内存优化)
java -Xms512m -Xmx1024m -jar target/my-springboot-app-1.0.0.jar \
  --spring.profiles.active=prod

2. 打包为WAR(用于外部容器)

修改Maven配置

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>com.example</groupId>
    <artifactId>my-springboot-app</artifactId>
    <version>1.0.0</version>
    <packaging>war</packaging>  <!-- 修改为WAR -->
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.1.5</version>
    </parent>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <!-- 排除内嵌Tomcat -->
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        
        <!-- 添加Servlet API依赖(provided scope) -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>  <!-- 由外部容器提供 -->
        </dependency>
    </dependencies>
    
    <build>
        <finalName>myapp</finalName>  <!-- WAR文件名称 -->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

修改启动类

package com.example;

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

@SpringBootApplication
public class MyApplication extends SpringBootServletInitializer {
    
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(MyApplication.class);
    }
    
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

Gradle WAR配置

plugins {
    id 'org.springframework.boot' version '3.1.5'
    id 'io.spring.dependency-management' version '1.1.3'
    id 'java'
    id 'war'  // 添加war插件
}

group = 'com.example'
version = '1.0.0'
sourceCompatibility = '17'

configurations {
    providedRuntime  // 用于provided范围的依赖
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat'
}

war {
    archiveFileName = 'myapp.war'
}

打包WAR

# Maven
mvn clean package

# Gradle
./gradlew clean build

部署到外部Tomcat

准备Tomcat服务器

# 下载Tomcat
wget https://downloads.apache.org/tomcat/tomcat-10/v10.1.13/bin/apache-tomcat-10.1.13.tar.gz
tar -xzf apache-tomcat-10.1.13.tar.gz
cd apache-tomcat-10.1.13

部署WAR文件

# 复制WAR文件到webapps目录
cp target/myapp.war /opt/tomcat/webapps/

# 或者使用管理界面部署
# 访问 http://localhost:8080/manager/html

Tomcat配置优化(conf/server.xml)

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443"
           maxThreads="200"
           minSpareThreads="10"
           enableLookups="false"
           acceptCount="100"
           disableUploadTimeout="true"/>

启动/停止Tomcat

# Linux
./bin/startup.sh
./bin/shutdown.sh

# Windows
bin\startup.bat
bin\shutdown.bat

3. 配置文件管理

application.yml 示例

# 公共配置
spring:
  application:
    name: my-springboot-app

# 开发环境
---
spring:
  config:
    activate:
      on-profile: dev
server:
  port: 8080
logging:
  level:
    root: DEBUG

# 生产环境
---
spring:
  config:
    activate:
      on-profile: prod
server:
  port: 8080
  compression:
    enabled: true
    mime-types: text/html,text/xml,text/plain,application/json
logging:
  file:
    name: /var/log/myapp.log
  level:
    root: INFO

4. 容器化部署(Docker)

Dockerfile for JAR

# 使用多阶段构建
FROM eclipse-temurin:17-jdk-alpine as builder
WORKDIR /app
COPY mvnw .
COPY .mvn .mvn
COPY pom.xml .
RUN ./mvnw dependency:go-offline
COPY src ./src
RUN ./mvnw clean package -DskipTests

# 运行阶段
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

Dockerfile for WAR + Tomcat

FROM tomcat:10.1-jdk17-temurin
# 移除默认应用
RUN rm -rf /usr/local/tomcat/webapps/*
# 复制WAR文件
COPY target/myapp.war /usr/local/tomcat/webapps/ROOT.war
# 暴露端口
EXPOSE 8080
# 启动Tomcat
CMD ["catalina.sh", "run"]

Docker Compose 示例

version: '3.8'
services:
  app:
    build: .
    ports:
      - "8080:8080"
    environment:
      - SPRING_PROFILES_ACTIVE=prod
      - DB_HOST=mysql
    depends_on:
      - mysql
    networks:
      - app-network

  mysql:
    image: mysql:8.0
    environment:
      - MYSQL_ROOT_PASSWORD=rootpass
      - MYSQL_DATABASE=mydb
    volumes:
      - mysql-data:/var/lib/mysql
    networks:
      - app-network

networks:
  app-network:
    driver: bridge

volumes:
  mysql-data:

三、部署脚本示例

Linux 服务脚本(systemd)

# /etc/systemd/system/myapp.service
[Unit]
Description=My Spring Boot Application
After=network.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
ExecStart=/usr/bin/java -Xms512m -Xmx1024m -jar myapp.jar
SuccessExitStatus=143
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target

部署脚本

#!/bin/bash
# deploy.sh

APP_NAME="my-springboot-app"
JAR_PATH="target/$APP_NAME-1.0.0.jar"
DEPLOY_DIR="/opt/$APP_NAME"
BACKUP_DIR="$DEPLOY_DIR/backup"
LOG_DIR="/var/log/$APP_NAME"

# 创建目录
mkdir -p $DEPLOY_DIR $BACKUP_DIR $LOG_DIR

# 备份旧版本
if [ -f "$DEPLOY_DIR/$APP_NAME.jar" ]; then
    TIMESTAMP=$(date +%Y%m%d_%H%M%S)
    mv "$DEPLOY_DIR/$APP_NAME.jar" "$BACKUP_DIR/$APP_NAME-$TIMESTAMP.jar"
fi

# 复制新版本
cp $JAR_PATH "$DEPLOY_DIR/$APP_NAME.jar"

# 设置权限
chmod 755 "$DEPLOY_DIR/$APP_NAME.jar"

# 重启服务
systemctl restart $APP_NAME

# 检查状态
sleep 10
systemctl status $APP_NAME

四、总结对比

特性JAR 部署WAR 部署
部署方式独立运行,内嵌容器依赖外部Servlet容器
启动命令java -jar app.jar容器启动(如Tomcat)
适合场景微服务、云原生、容器化传统企业环境、共享服务器
依赖管理包含所有依赖(fat jar)部分依赖由容器提供
资源占用每个应用独立容器多个应用共享容器资源
热部署需要重启整个应用Tomcat支持部分热部署
配置管理应用自身管理可与容器配置结合
监控Spring Boot Actuator容器管理界面 + Actuator

选择建议:

  1. 选择JAR的情况
    • 微服务架构
    • 容器化部署(Docker/K8s)
    • 云原生应用
    • 需要快速独立部署
    • 无现有应用服务器
  2. 选择WAR的情况
    • 传统企业IT环境
    • 已有Tomcat/WebLogic集群
    • 需要与其他Java EE应用共享资源
    • 运维团队熟悉传统部署模式
    • 需要与旧系统集成

最佳实践:

  1. 对于新项目,优先考虑JAR部署,更符合现代架构
  2. 统一配置管理:无论JAR/WAR,使用外部配置文件
  3. 健康检查:集成Spring Boot Actuator用于监控
  4. 日志集中:使用Logback/SLF4J,日志输出到文件或日志系统
  5. 安全加固:生产环境关闭开发特性,使用HTTPS
  6. 自动化部署:结合CI/CD流水线实现自动化

通过合理的打包部署策略,可以确保Spring Boot应用在不同环境中的稳定运行和高效维护。

以上就是SpringBoot JAR和WAR方式打包并部署的详细步骤及对比分析的详细内容,更多关于SpringBoot JAR和WAR方式打包部署的资料请关注脚本之家其它相关文章!

您可能感兴趣的文章:
阅读全文