Java 后端项目打包方式
1. 打包格式分类
1.1 按打包格式划分
| 格式 | 全称 | 用途 | 特点 |
|---|---|---|---|
| JAR | Java Archive | 标准 Java 包,可执行或依赖包 | 可独立执行,便于分发 |
| WAR | Web Application Archive | Web 应用包 | 包含 Web 组件,需容器运行 |
| EAR | Enterprise Archive | 企业级应用包 | 可包含多个模块,适用于复杂应用 |
1.2 打包格式选择指南
- JAR: 适用于微服务、独立应用或共享库
- WAR: 适用于传统 Web 应用,需要 Servlet 容器支持
- EAR: 适用于大型企业级应用,包含多个 Web 模块和 EJB 模块
2. 构建工具与打包方式
2.1 Maven 打包配置
基本 JAR 打包
xml
<!-- pom.xml -->
<project>
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>demo-app</artifactId>
<version>1.0.0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<build>
<plugins>
<!-- 1. 默认打包(不包含依赖) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.2.2</version>
<configuration>
<archive>
<manifest>
<mainClass>com.example.MainApplication</mainClass>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<!-- 2. 胖JAR/阴影JAR(包含所有依赖) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.2.4</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
<configuration>
<createDependencyReducedPom>false</createDependencyReducedPom>
<transformers>
<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
<mainClass>com.example.MainApplication</mainClass>
</transformer>
<!-- 解决META-INF文件冲突 -->
<transformer implementation="org.apache.maven.plugins.shade.resource.ServicesResourceTransformer"/>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.handlers</resource>
</transformer>
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
<resource>META-INF/spring.schemas</resource>
</transformer>
</transformers>
<filters>
<filter>
<artifact>*:*</artifact>
<excludes>
<exclude>META-INF/*.SF</exclude>
<exclude>META-INF/*.DSA</exclude>
<exclude>META-INF/*.RSA</exclude>
</excludes>
</filter>
</filters>
</configuration>
</execution>
</executions>
</plugin>
<!-- 3. 依赖复制插件(配合默认jar使用) -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
<overWriteReleases>false</overWriteReleases>
<overWriteSnapshots>false</overWriteSnapshots>
<overWriteIfNewer>true</overWriteIfNewer>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>Spring Boot 打包
xml
<!-- Spring Boot特定配置 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<version>2.7.0</version>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<mainClass>com.example.Application</mainClass>
<layout>JAR</layout>
<!-- 排除开发工具 -->
<excludeDevtools>true</excludeDevtools>
<!-- 可执行JAR和原始JAR都生成 -->
<classifier>exec</classifier>
</configuration>
</plugin>2.2 Gradle 打包配置
gradle
// build.gradle 或 build.gradle.kts
// Java插件
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
// Jar配置
jar {
manifest {
attributes 'Main-Class': 'com.example.Application'
}
}
// 胖JAR配置
jar {
enabled = true
manifest {
attributes 'Main-Class': 'com.example.Application'
}
from {
configurations.runtimeClasspath.collect { it.isDirectory() ? it : zipTree(it) }
}
}
// Spring Boot特定配置
bootJar {
manifest {
attributes 'Start-Class': 'com.example.Application'
}
}3. 不同场景的打包策略
3.1 微服务应用打包
xml
<!-- 微服务专用配置 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<image>
<name>my-registry/${project.artifactId}:${project.version}</name>
<publish>true</publish>
</image>
<layers>
<enabled>true</enabled>
</layers>
</configuration>
<executions>
<execution>
<id>build-image</id>
<phase>package</phase>
<goals>
<goal>build-image</goal>
</goals>
</execution>
</executions>
</plugin>
<!-- Jib插件用于构建优化的Docker镜像 -->
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<from>
<image>openjdk:17-jre-slim</image>
</from>
<to>
<image>registry.hub.docker.com/username/${project.artifactId}:${project.version}</image>
</to>
<container>
<jvmFlags>
<jvmFlag>-Xms512m</jvmFlag>
<jvmFlag>-Xmx1024m</jvmFlag>
</jvmFlags>
<mainClass>com.example.Application</mainClass>
</container>
</configuration>
</plugin>3.2 Docker 镜像打包
dockerfile
# 多阶段构建 Dockerfile
# 第一阶段:构建应用
FROM maven:3.8.5-openjdk-17 AS builder
WORKDIR /app
# 下载依赖(利用Docker缓存优化)
COPY pom.xml .
RUN mvn dependency:go-offline -B
# 复制源码并构建
COPY src ./src
ARG PROFILE=prod
RUN mvn clean package -DskipTests -Dspring.profiles.active=${PROFILE}
# 第二阶段:创建运行时镜像
FROM openjdk:17-jre-slim
# 安装必要的工具和字体
RUN apt-get update && apt-get install -y \
curl \
fontconfig \
&& rm -rf /var/lib/apt/lists/*
# 设置工作目录和时区
WORKDIR /app
ENV TZ=Asia/Shanghai
RUN ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone
# 复制应用JAR
COPY --from=builder /app/target/*.jar app.jar
# 创建非root用户
RUN groupadd -r appuser && useradd -r -g appuser appuser
RUN chown -R appuser:appuser /app
USER appuser
# 健康检查
HEALTHCHECK --interval=30s --timeout=10s --start-period=60s --retries=3 \
CMD curl -f http://localhost:8080/actuator/health || exit 1
# 暴露端口和启动命令
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "-Dspring.profiles.active=prod", "app.jar"]3.3 Web 应用打包(WAR)
xml
<project>
<!-- 更改打包类型 -->
<packaging>war</packaging>
<dependencies>
<!-- 移除内嵌Tomcat -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- 添加Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>java
// 修改启动类以支持WAR部署
@SpringBootApplication
public class Application extends SpringBootServletInitializer {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
return application.sources(Application.class);
}
}4. 高级打包技术
4.1 分层打包优化
xml
<!-- Spring Boot 2.3+ 分层打包 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<layers>
<enabled>true</enabled>
<configuration>${project.basedir}/layers.xml</configuration>
</layers>
</configuration>
</plugin>xml
<!-- layers.xml 自定义分层配置 -->
<layers xmlns="http://www.springframework.org/schema/boot/layers"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/boot/layers
https://www.springframework.org/schema/boot/layers/layers-2.5.xsd">
<application>
<into layer="spring-boot-loader">
<include>org/springframework/boot/loader/**</include>
</into>
<into layer="application" />
</application>
<dependencies>
<into layer="snapshot-dependencies">
<include>*:*:*SNAPSHOT</include>
</into>
<into layer="dependencies" />
</dependencies>
<layerOrder>
<layer>dependencies</layer>
<layer>spring-boot-loader</layer>
<layer>snapshot-dependencies</layer>
<layer>application</layer>
</layerOrder>
</layers>java
// 自定义分层配置
import org.springframework.boot.loader.tools.Layer;
import org.springframework.boot.loader.toolsLayers;
import java.util.Arrays;
import java.util.List;
public class CustomLayers implements Layers {
@Override
public List<String> getLayers() {
return Arrays.asList(
"dependencies", // 外部依赖,变化较少
"spring-boot-loader", // Spring Boot加载器
"snapshot-dependencies", // 快照版本依赖,变化频繁
"configuration", // 配置文件,可能变化
"application" // 应用代码,变化最频繁
);
}
}4.2 多模块项目打包
父 POM 聚合配置
xml
<!-- 父POM -->
<project>
<groupId>com.example</groupId>
<artifactId>multi-module-app</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>
<modules>
<module>core</module>
<module>service</module>
<module>web</module>
</modules>
<dependencyManagement>
<dependencies>
<!-- 核心模块 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>core</artifactId>
<version>${project.version}</version>
</dependency>
<!-- 服务模块 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>service</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>子模块依赖管理
xml
<!-- web模块POM -->
<project>
<parent>
<groupId>com.example</groupId>
<artifactId>multi-module-app</artifactId>
<version>1.0.0</version>
</parent>
<artifactId>web</artifactId>
<dependencies>
<!-- 依赖核心模块 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>core</artifactId>
</dependency>
<!-- 依赖服务模块 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>service</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>4.3 跨平台构建配置
xml
<!-- 使用Maven Assembly Plugin创建分发包 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-assembly-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<descriptors>
<descriptor>src/main/assembly/distribution.xml</descriptor>
</descriptors>
<tarLongFileMode>posix</tarLongFileMode>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>xml
<!-- distribution.xml -->
<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.1.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.1.0
http://maven.apache.org/xsd/assembly-2.1.0.xsd">
<id>distribution</id>
<formats>
<format>zip</format>
<format>tar.gz</format>
</formats>
<fileSets>
<fileSet>
<directory>${project.build.directory}</directory>
<outputDirectory>/</outputDirectory>
<includes>
<include>*.jar</include>
</includes>
</fileSet>
<fileSet>
<directory>src/main/scripts</directory>
<outputDirectory>/bin</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>src/main/config</directory>
<outputDirectory>/config</outputDirectory>
</fileSet>
</fileSets>
</assembly>5. 打包配置最佳实践
5.1 资源文件处理
xml
<build>
<resources>
<!-- 配置文件支持变量替换 -->
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*.properties</include>
<include>**/*.yml</include>
<include>**/*.yaml</include>
</includes>
</resource>
<!-- 静态资源不进行变量替换 -->
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*.xml</include>
<include>static/**</include>
<include>templates/**</include>
</includes>
</resource>
</resources>
<!-- 测试资源处理 -->
<testResources>
<testResource>
<directory>src/test/resources</directory>
<filtering>true</filtering>
</testResource>
</testResources>
</build>5.2 多环境配置打包
xml
<!-- Maven Profile配置 -->
<profiles>
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<activatedProperties>dev</activatedProperties>
</properties>
</profile>
<profile>
<id>test</id>
<properties>
<activatedProperties>test</activatedProperties>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<activatedProperties>prod</activatedProperties>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>jpg</nonFilteredFileExtension>
<nonFilteredFileExtension>png</nonFilteredFileExtension>
<nonFilteredFileExtension>gif</nonFilteredFileExtension>
<nonFilteredFileExtension>ico</nonFilteredFileExtension>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>yaml
# application.yml
spring:
profiles:
active: @activatedProperties@
config:
import: optional:file:./config/application-${spring.profiles.active}.yml5.3 打包命令示例
bash
# Maven 打包命令
mvn clean package -DskipTests # 跳过测试打包
mvn clean package -Pprod # 使用生产环境配置
mvn clean package -Dmaven.test.skip=true # 跳过测试
mvn clean install # 构建并安装到本地仓库
mvn clean deploy # 构建并部署到远程仓库
# Spring Boot 特定命令
mvn spring-boot:build-image # 构建 Docker 镜像
mvn spring-boot:run # 运行应用
mvn clean package spring-boot:repackage # 重新打包
# Gradle 打包命令
gradle clean build -x test # 跳过测试
gradle bootJar # 构建可执行 JAR
gradle bootBuildImage # 构建 Docker 镜像
gradle assemble # 构建所有发布版本
gradle publish # 发布到仓库6. 打包优化技巧
6.1 依赖优化
排除不必要的依赖
xml
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>true</excludeDevtools>
<excludeGroupIds>
org.springframework.boot.devtools,
org.springframework.boot,
org.projectlombok
</excludeGroupIds>
</configuration>
</plugin>
<!-- 在依赖声明中排除传递依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>依赖分析与优化
xml
<!-- Maven Dependency Analyzer Plugin -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>dependency-maven-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>analyze</id>
<goals>
<goal>analyze-only</goal>
</goals>
<configuration>
<failOnWarning>true</failOnWarning>
<ignoreNonCompile>false</ignoreNonCompile>
</configuration>
</execution>
</executions>
</plugin>bash
# 分析未使用的依赖
mvn dependency:analyze
# 显示依赖树
mvn dependency:tree
# 分析依赖大小
mvn dependency:analyze-duplicate6.2 资源优化
资源过滤和压缩
xml
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<encoding>UTF-8</encoding>
<nonFilteredFileExtensions>
<nonFilteredFileExtension>jpg</nonFilteredFileExtension>
<nonFilteredFileExtension>jpeg</nonFilteredFileExtension>
<nonFilteredFileExtension>gif</nonFilteredFileExtension>
<nonFilteredFileExtension>png</nonFilteredFileExtension>
<nonFilteredFileExtension>ico</nonFilteredFileExtension>
<nonFilteredFileExtension>pdf</nonFilteredFileExtension>
<nonFilteredFileExtension>zip</nonFilteredFileExtension>
</nonFilteredFileExtensions>
</configuration>
</plugin>
<!-- YUI Compressor 压缩JS和CSS -->
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.5.1</version>
<executions>
<execution>
<id>compress-js-css</id>
<phase>process-resources</phase>
<goals>
<goal>compress</goal>
</goals>
<configuration>
<sourceDirectory>src/main/resources/static</sourceDirectory>
<outputDirectory>target/classes/static</outputDirectory>
<excludes>
<exclude>**/*.min.js</exclude>
<exclude>**/*.min.css</exclude>
</excludes>
<jswarn>false</jswarn>
<nosuffix>true</nosuffix>
</configuration>
</execution>
</executions>
</plugin>6.3 代码混淆与保护
xml
<!-- ProGuard 混淆代码 -->
<plugin>
<groupId>com.github.wvengen</groupId>
<artifactId>proguard-maven-plugin</artifactId>
<version>2.5.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>proguard</goal>
</goals>
</execution>
</executions>
<configuration>
<proguardVersion>7.2.2</proguardVersion>
<injar>${project.build.finalName}.jar</injar>
<outjar>${project.build.finalName}-proguard.jar</outjar>
<libs>
<lib>${java.home}/lib/rt.jar</lib>
<lib>${java.home}/lib/jce.jar</lib>
</libs>
<obfuscate>true</obfuscate>
<options>
<option>-keep public class * { public *; }</option>
<option>-keep class com.example.Application { *; }</option>
<option>-dontwarn **</option>
<option>-dontshrink</option>
</options>
</configuration>
</plugin>7. 打包问题排查
7.1 常见打包问题及解决方案
依赖冲突
xml
<!-- Maven Enforcer Plugin 检测依赖冲突 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>3.0.0</version>
<executions>
<execution>
<id>enforce-versions</id>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<dependencyConvergence/>
<banDuplicateClasses>
<ignoreClasses>
<ignoreClass>org/slf4j/impl/StaticLoggerBinder.class</ignoreClass>
</ignoreClasses>
</banDuplicateClasses>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>资源缺失
xml
<!-- 强制复制所有资源 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-resources-plugin</artifactId>
<version>3.2.0</version>
<executions>
<execution>
<id>copy-resources</id>
<phase>validate</phase>
<goals>
<goal>copy-resources</goal>
</goals>
<configuration>
<outputDirectory>${project.build.outputDirectory}</outputDirectory>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>false</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</configuration>
</execution>
</executions>
</plugin>7.2 调试技巧
bash
# 开启Maven调试模式
mvn -X clean package
# 查看JAR包内容
jar tf target/myapp.jar
# 查看MANIFEST.MF内容
unzip -p target/myapp.jar META-INF/MANIFEST.MF
# 运行时调试
java -cp target/myapp.jar com.example.Application
java -verbose:class -jar target/myapp.jar8. 云原生打包最佳实践
8.1 云原生镜像优化
dockerfile
# 使用多阶段构建减小镜像体积
FROM eclipse-temurin:17-jdk-alpine AS builder
WORKDIR /app
COPY . .
RUN ./mvnw package -DskipTests
FROM eclipse-temurin:17-jre-alpine
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
# 添加非root用户
RUN addgroup -g 1000 appgroup && adduser -D -u 1000 -G appgroup appuser
USER appuser
# JVM优化参数
ENV JAVA_OPTS="-XX:+UseContainerSupport -XX:MaxRAMPercentage=75.0 -XX:+UseG1GC"
ENTRYPOINT ["sh", "-c", "java $JAVA_OPTS -jar app.jar"]8.2 Kubernetes 部署配置
yaml
# k8s-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
name: myapp
spec:
replicas: 3
selector:
matchLabels:
app: myapp
template:
metadata:
labels:
app: myapp
spec:
containers:
- name: myapp
image: registry.example.com/myapp:1.0.0
ports:
- containerPort: 8080
env:
- name: SPRING_PROFILES_ACTIVE
value: "k8s"
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1024Mi"
cpu: "500m"
livenessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 60
periodSeconds: 20
readinessProbe:
httpGet:
path: /actuator/health
port: 8080
initialDelaySeconds: 30
periodSeconds: 109. 总结
通过合理的打包配置,可以显著提升 Java 后端项目的部署效率和运行性能。选择适合项目需求的打包方式至关重要。以下是一些关键要点:
-
根据项目类型选择合适的打包格式:
- 单体应用通常选择 JAR
- 传统 Web 应用选择 WAR
- 大型企业应用考虑 EAR
-
针对不同场景采用合适的打包策略:
- 微服务应用使用分层 JAR 和 Docker 镜像
- 多模块项目合理管理依赖关系
- 云原生环境优化镜像大小和启动速度
-
优化打包过程:
- 排除不必要的依赖
- 压缩静态资源
- 考虑代码保护需求
-
采用云原生最佳实践:
- 多阶段 Docker 构建
- 非 root 用户运行
- 资源限制和健康检查
-
持续优化和监控:
- 定期检查依赖冲突
- 分析包大小变化
- 监控应用启动性能
通过以上策略,可以构建出高效、安全且易于部署的 Java 应用程序。
版本差异(Spring Boot 2.3+ → 3.5.x)
| 特性 | 旧版(Boot 2.3+ 分层打包) | 当前(Boot 3.5.x) |
|---|---|---|
| 分层打包工具 | layertools(jarmode) | 不变,java -Djarmode=layertools -jar 仍可用 |
| Buildpacks | 早期支持 | 官方主推(mvn spring-boot:build-image),免 Dockerfile |
| 可执行 jar | 传统 fat jar | 不变;新增 AOT 优化支持原生镜像 |
| 部署方式 | 传统 / 容器 | 容器(分层镜像)+ 原生镜像(GraalVM)并行 |
| JDK | 8/11 | 17-24 |
本文的 jar/war 打包、Dockerfile 分层、docker-maven-plugin(3.3.x)方案在 Boot 3.5.x 中依然有效;新项目可优先尝试
spring-boot:build-image(Cloud Native Buildpacks),无需手写 Dockerfile。