【java打包方式详解】

java打包方式详解

  • [一、配置内置 + 启动时指定环境(最常用)](#一、配置内置 + 启动时指定环境(最常用))
  • 二、配置外置(JAR与配置分离)
    • [3. 配置文件放在JAR外(--spring.config.location)](#3. 配置文件放在JAR外(--spring.config.location))
    • [4. 通过环境变量注入配置](#4. 通过环境变量注入配置)
    • [5. 配置中心(集中式配置管理)](#5. 配置中心(集中式配置管理))
  • 三、容器化方案(Docker/K8s)
    • [6. 多阶段构建 + 镜像标签区分环境](#6. 多阶段构建 + 镜像标签区分环境)
    • [7. Kubernetes ConfigMap + Secret](#7. Kubernetes ConfigMap + Secret)
  • 四、其他特殊方案
    • [8. 依赖分离打包(lib与jar分离)](#8. 依赖分离打包(lib与jar分离))
    • [9. Systemd服务 + 环境配置文件](#9. Systemd服务 + 环境配置文件)
    • [10. 通过JVM系统属性覆盖](#10. 通过JVM系统属性覆盖)

在开发过程中,当我们发布应用时,需要进行打包,此时有很多种方法
各种方法对比

方法 打包次数 配置位置 安全性 运维复杂度 适用场景
Profile + 启动参数 1次 JAR内+外覆写 中小项目,环境数少
Maven多Profile N次(N个环境) JAR内 安全要求高,环境隔离严格
配置外置 1次 服务器目录 配置经常变更
环境变量 1次 环境变量 云原生,12-Factor App
配置中心 1次 配置中心 大型微服务架构
Kubernetes ConfigMap 1次 K8s集群 容器化部署

一、配置内置 + 启动时指定环境(最常用)

1. 多Profile配置文件 + spring.profiles.active

打包:一个JAR包含所有环境的配置文件(application-dev.yml、application-prod.yml等)

如图,每个文件对应一个环境

打包方法

1.命令打包

bash 复制代码
mvn clean package

2.maven界面

在maven命令界面找到我们的服务,点击package

打包完成后即可看到jar包路径

部署

部署:启动时通过参数激活指定环境

在启动命令中指定环境

bash 复制代码
java -jar app.jar --spring.profiles.active=prod
# 或使用环境变量
export SPRING_PROFILES_ACTIVE=prod
java -jar app.jar

优缺点

优点 :一个JAR通吃所有环境,部署灵活
缺点:JAR体积稍大,所有配置暴露(有安全风险)

2. Maven构建时指定Profile(配置过滤)

在pom文件配置如下

java 复制代码
<profiles>
    <profile>
        <id>dev</id>
        <properties><env>dev</env></properties>
    </profile>
    <profile>
        <id>prod</id>
        <properties><env>prod</env></properties>
    </profile>
</profiles>

<build>
    <resources>
        <resource>
            <directory>src/main/resources</directory>
            <filtering>true</filtering>
        </resource>
    </resources>
</build>

打包:构建时指定环境

命令打包

bash 复制代码
mvn clean package -Pprod

界面打包

部署:直接启动(环境已固化在JAR内)

bash 复制代码
java -jar app-prod.jar

优缺点

优点 :JAR内无多余配置,安全性高
缺点:每个环境需单独打包,易产生版本不一致

二、配置外置(JAR与配置分离)

3. 配置文件放在JAR外(--spring.config.location)

打包:只打包代码,不包含配置文件(或仅包含默认配置)

bash 复制代码
mvn clean package

部署:配置文件放在服务器指定目录,启动时指定外部配置

bash 复制代码
java -jar app.jar --spring.config.location=/opt/config/application.yml
# 或使用优先级更高的目录
java -jar app.jar --spring.config.location=file:/opt/external/

Spring Boot默认外部配置优先级:

  • 1.当前目录的/config子目录

  • 2.当前目录

  • 3.classpath的/config包

  • 4.classpath根目录

优点 :修改配置无需重新打包,运维友好
缺点:需额外管理配置文件分发

4. 通过环境变量注入配置

打包 :标准JAR包
部署:通过环境变量覆盖配置

bash 复制代码
export SERVER_PORT=8081
export SPRING_DATASOURCE_URL=jdbc:mysql://prod-db:3306/app
java -jar app.jar

或使用.env文件配合工具(如systemd的EnvironmentFile)

优点 :符合12-Factor App原则,适合容器化
缺点:复杂配置管理不便

5. 配置中心(集中式配置管理)

打包:JAR包仅包含配置中心客户端配置(如nacos、apollo、consul的地址)

java 复制代码
# application.yml
spring:
  cloud:
    nacos:
      config:
        server-addr: config-center:8848
        namespace: ${ENV:dev}

部署

bash 复制代码
java -jar app.jar -DENV=prod

配置中心存储所有环境的完整配置

优点 :动态刷新、统一管理、审计日志、灰度发布
缺点:引入额外基础设施,增加复杂度

三、容器化方案(Docker/K8s)

6. 多阶段构建 + 镜像标签区分环境

Dockerfile:

bash 复制代码
FROM openjdk:11
COPY target/app.jar /app.jar
ENTRYPOINT ["java", "-jar", "/app.jar", "--spring.profiles.active=${SPRING_PROFILE}"]

部署

bash 复制代码
# 构建一次镜像
docker build -t myapp:latest .

# 不同环境启动时传入不同环境变量
docker run -e SPRING_PROFILE=dev -p 8080:8080 myapp:latest
docker run -e SPRING_PROFILE=prod -p 8080:8080 myapp:latest

7. Kubernetes ConfigMap + Secret

打包 :镜像内不包含环境配置
部署

yaml 复制代码
apiVersion: v1
kind: ConfigMap
metadata:
  name: app-config
data:
  application-prod.yml: |
    server:
      port: 8080
    spring:
      datasource:
        url: jdbc:mysql://prod-db:3306/app
---
apiVersion: apps/v1
kind: Deployment
spec:
  template:
    spec:
      containers:
      - name: app
        image: myapp:latest
        env:
        - name: SPRING_PROFILES_ACTIVE
          value: "prod"
        volumeMounts:
        - name: config
          mountPath: /config
      volumes:
      - name: config
        configMap:
          name: app-config

四、其他特殊方案

8. 依赖分离打包(lib与jar分离)

原理:将依赖的JAR放到外部目录,业务代码单独打包(减小主JAR体积)

bash 复制代码
# 使用maven-jar-plugin和maven-dependency-plugin
mvn dependency:copy-dependencies -DoutputDirectory=lib

启动

bash 复制代码
java -cp "lib/*:myapp.jar" com.example.Main

或使用Spring Boot的PropertiesLauncher:

bash 复制代码
# 在application.properties
loader.path=lib/
bash 复制代码
java -Dloader.path=lib/ -jar myapp.jar

优点 :更新业务代码时无需重新上传依赖
缺点:启动命令复杂,易出错

9. Systemd服务 + 环境配置文件

打包 :标准JAR包
部署:创建systemd service文件

bash 复制代码
[Unit]
Description=MyApp
After=network.target

[Service]
Type=simple
User=appuser
WorkingDirectory=/opt/myapp
EnvironmentFile=/opt/myapp/env.conf
ExecStart=/usr/bin/java -jar /opt/myapp/app.jar
Restart=on-failure

[Install]
WantedBy=multi-user.target

env.conf:

bash 复制代码
SPRING_PROFILES_ACTIVE=prod
SERVER_PORT=8080

10. 通过JVM系统属性覆盖

打包 :标准JAR
部署:启动时使用-D参数

bash 复制代码
java -Dspring.profiles.active=prod \
     -Dserver.port=8081 \
     -Dspring.datasource.url=jdbc:mysql://prod-db:3306/app \
     -jar app.jar

适合少量配置,或配合脚本动态生成

相关推荐
Yeh2020582 小时前
maven
java·maven
ths5122 小时前
测试开发python中正则表达式使用总结(二)
开发语言·python·算法
人道领域2 小时前
2026年Java后端热点全景解析:从LTS革新到云原生跃迁
java·开发语言
heimeiyingwang2 小时前
【架构实战】API接口防刷与限流策略
开发语言·python·架构
188号安全攻城狮2 小时前
【前端基础知识】JavaScript 数组方法总结:从表格速查到分类详解
开发语言·前端·javascript·网络安全
鱼鳞_2 小时前
Java学习笔记_Day26(不可变集合)
java·笔记·学习
不爱吃炸鸡柳2 小时前
5道经典贪心算法题详解:从入门到进阶
开发语言·数据结构·c++·算法·贪心算法
zhaoyufei1332 小时前
RK3566 EDP屏幕背光闪修改pwm
android·java
xyq20242 小时前
Java 变量命名规则
开发语言