一、背景介绍
一般 SpringBoot 的项目依赖 Jar 大小维持在 40MB ~ 160MB。SpringBoot 程序 Jar 包就是这些 Classes 文件和依赖的 Jar 组成,这些依赖 Jar几乎占了这个应用 Jar 包的全部大小。
当我们写一个程序的时候,常常所依赖的 Jar 不会经常变动,变动多的是源代码程序,依赖的 Jar 包非常大而源代码非常小。
二、如何解决 lib 和 class 文件分离
发现 SpringBoot 的 Maven 插件在执行 Maven 编译打 Jar 包时候做了很多事情,如果改变某些插件的打包逻辑,致使打应用 Jar 时候将 lib 文件夹下所有的 Jar 包都拷贝到应用 Jar 外面,只留下编译好的字节码文件。
将这几个 Maven 工具引入到项目 pom.xml 中
<build>
<plugins>
<!--设置应用 Main 参数启动依赖查找的地址指向外部 lib 文件夹-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<classpathPrefix>lib/</classpathPrefix>
</manifest>
</archive>
</configuration>
</plugin>
<!--设置 SpringBoot 打包插件不包含任何 Jar 依赖包-->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<includes>
<include>
<groupId>nothing</groupId>
<artifactId>nothing</artifactId>
</include>
</includes>
</configuration>
</plugin>
<!--设置将 lib 拷贝到应用 Jar 外面-->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>copy-dependencies</id>
<phase>prepare-package</phase>
<goals>
<goal>copy-dependencies</goal>
</goals>
<configuration>
<outputDirectory>${project.build.directory}/lib</outputDirectory>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
执行 Maven 命令打包 Jar
mvn clean install
当 Maven 命令执行完成后,查看 target 目录如下图:
三、测试
java -jar eureka-test-0.0.1-SNAPSHOT.jar
可以看到项目是可以起来正常访问。
四、可以改造Springboot 编译 Docker 镜像
Dockerfile
FROM openjdk:8u212-b04-jre-slim
VOLUME /tmp
COPY target/lib/ ./lib/
ADD target/*.jar app.jar
RUN sh -c 'touch /app.jar'
ENV JAVA_OPTS="-Duser.timezone=Asia/Shanghai"
ENV APP_OPTS=""
ENTRYPOINT [ "sh", "-c", "java $JAVA_OPTS -Djava.security.egd=file:/dev/./urandom -jar /app.jar $APP_OPTS" ]
这里新增了一层指令,作用为将 lib 文件夹复制到镜像之中,由于 Docker 缓存机制原因,这层一定要在复制应用 Jar 之前,这样改造后每次只要 lib/ 文件夹里面的依赖 Jar 不变,就不会新创建层,而是复用缓存。
评论区