Spring Boot 项目瘦身指南,瘦到不可思议!129M

您所在的位置:网站首页 maven打包太大清除所有依赖 Spring Boot 项目瘦身指南,瘦到不可思议!129M

Spring Boot 项目瘦身指南,瘦到不可思议!129M

2023-07-07 13:29| 来源: 网络整理| 查看: 265

之前在 从使用传统Web框架到切换到Spring Boot后的总结 中提到关于 Spring Boot 编译打包,Spring Boot 应用程序不用额外部署到外部容器中,可以直接通过 Maven 命令将项目编译成可执行的 jar 包,然后通过 java -jar 命令启动即可,非常方便。

最近有小伙伴私信我说,打 jar 包方便是方便,就是每次打包出来的 jar 太大了,先不说上传时间的问题,如果只修改了 1 个类就需要重新打包项目,然后重新上传项目到服务器,怎么觉得还不如我之前使用 war 包方便呢,使用 war 包时,虽然要部署到 Tomcat 中,但只需要将修改的 class 替换一下,重启一下 Tomcat 就可以了。。。

其实到底选择哪种打包方式,主要还是看个人习惯和业务场景需求,毕竟 Spring Boot 也支持打包 war 包的。

今天的重点不是打包方式,而是解决困惑了小伙伴打包的 jar 太大的问题。

正常打包项目

给 Spring Boot 打包大家应该很熟了吧,只需要在 pom.xml 文件中配置 spring-boot-maven-plugin 打包插件:

                        org.springframework.boot            spring-boot-maven-plugin            

然后在项目根目录执行 mvn clean pavkage 就可以完成打包了,如下是我本地的一个项目打包情况:

可以看到打包出的 jar 应用是相当的大了,如小伙伴说的一样,如果每次修改一个 class 文件或者配置文件,就需要重新打包然后上传服务器的话,那确实是太麻烦了,可能上传就浪费大部分时间。。。

应用瘦身(分离lib和配置文件)

其实 jar 包大的原因在于所有的依赖包全部集成在 jar 包里面,如下是瘦身前的 jar 包内部结构:

其中 classes 就是我们项目的代码,仅仅1.3M,而 129MB 的 lib 目录是项目中所有的依赖(比如spinrg、Hibernate等依赖),如果我们能把这个 lib 目录提取出来,整个项目就会变得特别小了。说干就干。

我们知道 Spring Boot 的打包终究是依赖于 Maven ,所以想到更改打包信息,无非就是指定 Maven 的配置。

在 pom.xml 添加如下信息(后文解释):

   你想要的jar包名称                              org.springframework.boot            spring-boot-maven-plugin                                            true                                true                                                                            nothing                        nothing                                                                                                                        repackage                                                                                    org.apache.maven.plugins            maven-compiler-plugin                                           ${java.version}                                ${java.version}                                UTF-8                                                                                              ${java.home}/lib/rt.jar:${java.home}/lib/jce.jar                                        ${java.home}/lib/rt.jar:${java.home}/lib/jce.jar                                    

                            org.apache.maven.plugins            maven-dependency-plugin                                                copy-dependencies                    prepare-package                                            copy-dependencies                                                                                      ${project.build.directory}/lib                        false                        false                        true                                                                                        org.apache.maven.plugins            maven-jar-plugin                                                                                                true                                                lib/                                                com.javam4.MyApplication                                                                                                            *.properties                    *.xml                    *.yml                                    

    

如下一一细拆如上配置:

1、spring-boot-maven-plugin

Springboot 默认使用 spring-boot-maven-plugin 来打包,这个插件会将项目所有的依赖打入项目 jar 包里面,正常打包时 spring-boot-maven-plugin 结构如下:

      org.springframework.boot       spring-boot-maven-plugin                com.javam4.MyApplication          ZIP                                            repackage                           

如下是提取的修改项:

        true        true                            nothing            nothing            

修改的作用:

includeSystemScope:jar包分两种,一种是spring、mybatis等这种项目依赖的,再就是我们外部手动引入的第三方 jar 依赖,如果该参数不设置为 true 的话是不能被打包进来的~ includes:这个节点就是排除项目中所有的 jar,那还怎么打包?

其实我们需要将打包插件替换为 maven-jar-plugin,然后使用该插件拷贝依赖到 jar 到外面的 lib 目录。

2、maven-xxx-plugin

从 2、3、4 你会发现用到了 maven-xxx-plugin 格式的三种插件,简单说一下这三者的作用:

maven-compiler-plugin:

完成对Java代码的编译,可以指定项目源码的jdk版本、编译后的jdk版本,以及编码,如果不写这个插件也是没问题的,不写会使用默认的 jdk 版本来处理,只是这样容易出现版本不匹配的问题,比如本地maven环境用的3.3.9版本,默认会使用jdk1.5进行编译,而项目中用的jdk1.8的编译环境,那就会导致打包时编译不通过。

maven-dependency-plugin:

作用就是将所有依赖的jar文件复制到指定目录下,其中涉及到的 ${project.xx} 见下文补充。

maven-jar-plugin:

主要作用就是将maven工程打包成jar包。

主要说一下 maven-jar-plugin 插件的如下配置:

                        *.properties        *.xml        *.yml    

打包时排除资源配置文件,如果排除了配置文件那么项目启动是怎么读取呢?

配置文件有这么一个默认的优先级:

当前项目config目录下 > 当前项目根目录下 > 类路径config目录下 > 类路径根目录下

因此只需要将配置文件复制一份到与 jar 包平级目录下,或者与jar包平行config目录下,就能优先使用此配置文件,达到了伪分离目的。

最终的目录结构如下:

Maven 中的内置变量说明:

${basedir} 项目根目录 ${project.build.directory} 构建目录,缺省为target ${project.build.outputDirectory} 构建过程输出目录,缺省为target/classes ${project.build.finalName} 产出物名称,缺省为{project.artifactId}-${project.version} ${project.packaging} 打包类型,缺省为jar ${project.packaging} 打包类型,缺省为jar ${project.xxx} 当前pom文件的任意节点的内容 瘦身总结

Spring Boot 框架提供了一套自己的打包机制 — spring-boot-maven-plugin,Springboot 默认使用该插件来打包,打包时会将项目所有的依赖打入项目 jar 包里面,如果我们想要抽离依赖的 jar 仅仅使用该插件是不行的,就需要将打包插件替换为 maven-jar-plugin,并拷贝所有的依赖到 jar 外面的 lib 目录。

项目打包时,在分离依赖 jar 包基础上,我们又排除了配置文件,因为配置文件有一个默认的读取路径:

当前项目config目录下 > 当前项目根目录下 > 类路径config目录下 > 类路径根目录下

我们只需要在当前项目 jar 包同级目录创建一个 config 文件夹,然后将配置文件复制一份,这样就达到了伪分离目的。

之后再修改配置文件,比如端口号、数据库连接信息等,就不需要重新打包项目了,直接修改完配置文件重启项目就可以了。

而经过分离依赖后的 jar 包从原来的100多兆到现在的1兆,如果后面需要变更业务逻辑,只需要轻量的编译项目,快速的实现项目的上传替换,有效的减少了网络开销,提高项目部署的效率。

博客地址:https://niceyoo.cnblogs.com

更多原创内容可以移步我的公众号,回复「面试」获取我整理的2020面经。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3