Spring Boot 部署与打包方式详解(Jar vs War)

发布于:2025-06-30 ⋅ 阅读:(18) ⋅ 点赞:(0)

Spring Boot 提供了灵活的打包选项,支持两种主要部署方式:可执行 JAR传统 WAR。以下是全面的对比与实践指南,帮助你根据项目需求选择最适合的部署方案。


📦 一、打包方式对比

特性 可执行 JAR (默认) 传统 WAR
启动方式 java -jar app.jar 部署到外部 Servlet 容器 (如 Tomcat)
内嵌服务器 ✅ 包含 Tomcat/Jetty/Undertow ❌ 需外部容器
部署复杂度 ⭐ 极简 (单文件部署) ⭐⭐⭐ 需容器环境
依赖管理 所有依赖打包进单个 FAT JAR 依赖由容器管理 (部分依赖可打包进 WAR)
热更新 需第三方工具 (JRebel) 支持容器级热部署
生产适用场景 微服务/云原生环境 传统企业级应用服务器环境
文件大小 较大 (包含内嵌容器) 较小 (仅应用代码)

🛠️ 二、JAR 打包部署 (默认方式)

1. 打包配置 (Maven)

确保你的 pom.xml 文件中有如下插件配置:

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

2. 打包命令

使用 Maven 进行构建:

mvn clean package
# 生成 target/appname-0.0.1-SNAPSHOT.jar

3. 运行方式

可以采用多种方式运行 JAR 文件:

# 标准启动
java -jar app.jar

# 带配置文件启动
java -jar -Dspring.profiles.active=prod app.jar

# 内存限制启动
java -Xms512m -Xmx1024m -jar app.jar

4. 生产环境增强

为了更好地适应生产环境,你可以采取以下措施:

  • 系统服务化 (Systemd):
[Unit]
Description=Spring Boot Service
After=syslog.target

[Service]
User=appuser
ExecStart=/usr/bin/java -jar /opt/app/app.jar
SuccessExitStatus=143
  • 启动脚本封装 (带日志分割):
nohup java -jar app.jar > app.log 2>&1 &

🧩 三、WAR 打包部署 (传统方式)

1. 修改打包类型

首先,在 pom.xml 中将 <packaging> 修改为 war

<packaging>war</packaging>

2. 排除内嵌容器 (Tomcat)

由于 WAR 文件需要部署到外部容器中,因此需要排除内置的 Tomcat:

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

3. 初始化 Servlet 入口

修改主类以继承 SpringBootServletInitializer

public class Application extends SpringBootServletInitializer {
    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(Application.class);
    }

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

4. 构建与部署

完成上述步骤后,执行打包命令并部署到 Tomcat:

mvn clean package
# 生成 target/appname-0.0.1-SNAPSHOT.war

# 部署到 Tomcat
cp target/app.war $TOMCAT_HOME/webapps/

☁️ 四、云原生部署最佳实践

1. Docker 容器化部署 (JAR 方式)

编写 Dockerfile 来创建镜像:

FROM eclipse-temurin:17-jre
VOLUME /tmp
COPY target/*.jar app.jar
ENTRYPOINT ["java","-jar","/app.jar"]

然后构建和运行 Docker 镜像:

docker build -t myapp:1.0 .
docker run -d -p 8080:8080 myapp:1.0

2. 多阶段构建优化镜像

利用多阶段构建来减小最终镜像体积:

# 阶段1:构建应用
FROM maven:3.8.6 AS build
COPY src /app/src
COPY pom.xml /app
RUN mvn -f /app/pom.xml clean package

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

3. Kubernetes 部署

定义 Deployment 和 Service YAML 文件来进行 Kubernetes 部署:

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: springboot-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: springboot
  template:
    metadata:
      labels:
        app: springboot
    spec:
      containers:
      - name: app
        image: myregistry/springboot-app:1.0
        ports:
        - containerPort: 8080
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: prod
---
# service.yaml
apiVersion: v1
kind: Service
metadata:
  name: springboot-service
spec:
  selector:
    app: springboot
  ports:
    - protocol: TCP
      port: 80
      targetPort: 8080

⚠️ 五、关键注意事项

  1. 静态资源处理
    JAR 模式:资源放在 src/main/resources/static
    WAR 模式:资源放在 src/main/webapp

  2. 配置文件优先级
    Spring Boot 加载顺序:

1. jar 内部 application.properties  
2. jar 同级 /config/ 目录  
3. jar 同级目录  
4. 类路径 /config  
5. 类路径根目录
  1. 上下文路径设置
    JAR 模式:server.servlet.context-path=/api
    WAR 模式:通过容器设置或 application.properties

  2. 端口冲突解决

# 避免与容器端口冲突
server.port=8081
  1. WAR 部署常见问题
    类冲突:使用 <scope>provided</scope> 排除容器已有库
    路径错误:确保 SpringBootServletInitializer 正确配置

🔍 六、部署决策树

在这里插入图片描述


🚀 七、高级部署方案

  1. 性能优化启动
# 开启 AOT 优化 (Spring Boot 3+)
java -Dspring.aot.enabled=true -jar app.jar
  1. GraalVM 原生镜像
# 需配置 spring-boot-starter-parent 3.x
mvn native:compile -Pnative
  1. 蓝绿部署方案
负载均衡
版本A
版本B
  1. 健康检查端点
management:
  endpoint:
    health:
      probes:
        enabled: true # 启用K8s就绪/存活检查
  health:
    livenessstate:
      enabled: true
    readinessstate:
      enabled: true

💎 总结建议

  • 优先选择 JAR: 对于大多数微服务和云原生应用来说,JAR 是理想的选择。
  • 选择 WAR 当: 需要与遗留系统集成或必须在特定应用服务器上运行时考虑使用 WAR。

  • 如果你在学习过程中遇到任何问题,欢迎在评论区留言交流!
  • 👍 如果你觉得这篇文章对你有帮助,别忘了点赞、收藏、转发哦!

网站公告

今日签到

点亮在社区的每一天
去签到