SpringBoot JAR和WAR方式打包并部署的详细步骤及对比分析
作者:悟空码字
无论选择JAR还是WAR部署方式,关键在于匹配团队的技术栈、运维能力和业务需求,Spring Boot的灵活性支持两种部署模式,为不同场景提供了合适的解决方案,本文给大家详细对比分析了这两种方式,需要的朋友可以参考下
一、JAR 和 WAR 打包的区别
JAR (Java ARchive)
- 独立运行:内嵌Tomcat/Jetty服务器,可直接通过
java -jar运行 - 微服务友好:适合云原生、容器化部署
- 简化部署:单个可执行文件,无需外部Web服务器
- 默认方式:Spring Boot 默认打包为可执行JAR
WAR (Web Application ARchive)
- 传统部署:需要外部Servlet容器(如Tomcat、WebLogic)
- 企业环境:适合需要部署到现有应用服务器的场景
- 共享资源:多个应用可共享服务器资源
- 配置分离:服务器配置与应用分离
二、详细打包部署步骤
项目结构
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 |
选择建议:
- 选择JAR的情况:
- 微服务架构
- 容器化部署(Docker/K8s)
- 云原生应用
- 需要快速独立部署
- 无现有应用服务器
- 选择WAR的情况:
- 传统企业IT环境
- 已有Tomcat/WebLogic集群
- 需要与其他Java EE应用共享资源
- 运维团队熟悉传统部署模式
- 需要与旧系统集成
最佳实践:
- 对于新项目,优先考虑JAR部署,更符合现代架构
- 统一配置管理:无论JAR/WAR,使用外部配置文件
- 健康检查:集成Spring Boot Actuator用于监控
- 日志集中:使用Logback/SLF4J,日志输出到文件或日志系统
- 安全加固:生产环境关闭开发特性,使用HTTPS
- 自动化部署:结合CI/CD流水线实现自动化
通过合理的打包部署策略,可以确保Spring Boot应用在不同环境中的稳定运行和高效维护。
以上就是SpringBoot JAR和WAR方式打包并部署的详细步骤及对比分析的详细内容,更多关于SpringBoot JAR和WAR方式打包部署的资料请关注脚本之家其它相关文章!
