文章目录

  • 一、概述
  • 二、工程概况
  • 1. 代码原始结构
  • 2. 运行界面
  • 三、常规打包
  • 1. 打包命令
  • 2. jar包结构
  • 四、分离依赖包、执行包步骤
  • 1. 引入依赖包管理插件
  • 2. 打包验证
  • 五、分离后构建docker 镜像
  • 1. 借助Dockerfile
  • 2. docker-maven-plugin实现
  • 六、版本升级


一、概述

某大数据项目,使用springboot常规打包方式,打出来的一体化执行包达几百兆, 分析jar 结构,其中的依赖包达几百个,占据99%以上的体积。
考虑到在迭代开发小版本升级发布期间,依赖包几乎不会发生变化。迫切需要将依赖包和执行包分离,部署时在依赖包不变的情况下只更新执行包,来提升发布效率。

下面我们以 springboot-hello 工程为例来说明操作过程。

二、工程概况

1. 代码原始结构

此工程为普通的springboot工程,大家可以 下载源码 运行 HelloApplication

spring boot 项目没有自动下载依赖 springboot依赖包下载_docker

2. 运行界面

spring boot 项目没有自动下载依赖 springboot依赖包下载_后端_02


点击doc.html为在线接口文档

spring boot 项目没有自动下载依赖 springboot依赖包下载_spring boot_03


点击h2-console打开内存数据库登录页面

spring boot 项目没有自动下载依赖 springboot依赖包下载_docker_04


JDBC URL 填入 jdbc:h2:mem:hello;database_to_upper=false,User Name 填入sa,点击Connect

spring boot 项目没有自动下载依赖 springboot依赖包下载_docker_05

三、常规打包

1. 打包命令

进入项目目录执行打包

mvn clean package

执行结果如下:

spring boot 项目没有自动下载依赖 springboot依赖包下载_后端_06

可以看到除了生成jar外,还生成了docker镜像。
注意:生成镜像需要本地docker环境,本人使用了Windows系统下的Docker Desktop

如果推送到镜像仓库的话,需打开<goal>push</goal>并配置镜像仓库账号、密码,有2种方式:
1.在maven配置文件中配置,可参考:容器镜像生成记

2.项目pom.xml文件中配置

spring boot 项目没有自动下载依赖 springboot依赖包下载_依赖包_07


将上图${docker.username}、${docker.password} 替换为实际的值。

2. jar包结构

进入target目录查看,有下图2个文件

spring boot 项目没有自动下载依赖 springboot依赖包下载_docker_08

springboot-hello-1.0.0.jar为包含依赖包的可执行包,大小50MB
springboot-hello-1.0.0.jar.original为不包含依赖包的原始包,大小1.5MB
通过对比,我们看到依赖包百分比为97%,也就是一次部署升级绝大部分的内容是不变的,变动的只是class文件、配置文件

依赖包位置如下:

spring boot 项目没有自动下载依赖 springboot依赖包下载_docker_09

四、分离依赖包、执行包步骤

1. 引入依赖包管理插件

拷贝pom.xml重命名为pom-with-libs.xml 移除spring-boot-maven-plugin、docker-maven-plugin添加maven-dependency-plugin、maven-jar-plugin 注意需要移除 lombok,spring-boot-devtools 依赖,实现拷贝依赖包到libs目录,并在jar指定依赖包位置和主函数。

核心配置如下:

<!-- 将项目依赖包复制到<outputDirectory>指定的目录下 -->
			<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}/libs</outputDirectory>
							<excludeArtifactIds>lombok,spring-boot-devtools</excludeArtifactIds>
							<includeScope>runtime</includeScope><!-- 默认为test,包含所有依赖 -->
						</configuration>
					</execution>
				</executions>
			</plugin>

			<!-- 将项目依赖包的路径(与上一项中的<outputDirectory>对应)添加到classPath中 -->
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-jar-plugin</artifactId>
				<configuration>
					<archive>
						<manifest>
							<addClasspath>true</addClasspath>
							<classpathPrefix>libs</classpathPrefix>
							<mainClass>com.fly.HelloApplication</mainClass>
						</manifest>
						<manifestEntries>
							<Class-Path>./</Class-Path>
						</manifestEntries>
					</archive>
				</configuration>
			</plugin>

2. 打包验证

执行打包

mvn clean package -f pom-with-libs.xml

执行结果:

spring boot 项目没有自动下载依赖 springboot依赖包下载_依赖包_10


我们看到,已经生成了依赖包和执行包,并且执行包指定了依赖包位置‘

spring boot 项目没有自动下载依赖 springboot依赖包下载_jar_11


进入target 目录,运行命令 java -jar springboot-hello-libs-1.0.0.jar ,启动正常

五、分离后构建docker 镜像

具体分2种方式,简单说明如下

1. 借助Dockerfile

具体见

spring boot 项目没有自动下载依赖 springboot依赖包下载_spring boot_12


测试时,将Dockerfile pom.xml移动上一层目录,运行mvn clean package即可。

2. docker-maven-plugin实现

具体参见: pom-with-libs-docker.xml 核心配置为:

spring boot 项目没有自动下载依赖 springboot依赖包下载_docker_13

测试时,运行mvn clean package -f pom-with-libs-docker.xml即可

六、版本升级

依赖包未变化的情况下,只需修改Dockerfile文件类似下面内容即可

FROM registry.cn-shanghai.aliyuncs.com/00fly/springboot-hello-libs:1.0.0
COPY target/*.jar  /app.jar

有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!

-over-