java打包方式详解
- [一、配置内置 + 启动时指定环境(最常用)](#一、配置内置 + 启动时指定环境(最常用))
-
- [1. 多Profile配置文件 + spring.profiles.active](#1. 多Profile配置文件 + spring.profiles.active)
- [2. Maven构建时指定Profile(配置过滤)](#2. Maven构建时指定Profile(配置过滤))
- 二、配置外置(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
适合少量配置,或配合脚本动态生成