SpringBoot 项目瘦身maven/gradle详解
maven thin jar 步骤
spring-boot-maven-plugin configuration layout ZIP includes include non-exists maven-dependency-plugin excutions excution goal copy-dependencies configuration outputDirectory
<build> <finalName>thin-jar</finalName> <!--java -jar -Dloader.path=./lib thin-jar.jar--> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring.boot.version}</version> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> <configuration> <!-- fork=true 新开 Jvm 运行插件 --> <fork>true</fork> <addResources>true</addResources> <jvmArguments>-Dfile.encoding=UTF-8</jvmArguments> <layout>ZIP</layout> <includes> <include> <groupId>non-exists</groupId> <artifactId>non-exists</artifactId> </include> </includes> </configuration> </plugin> <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> <!--是否排除传递性--> <excludeTransitive>false</excludeTransitive> <!--是否去掉jar包版本信息--> <stripVersion>false</stripVersion> <!--包含范围--> <includeScope>runtime</includeScope> </configuration> </execution> </executions> </plugin> </plugins> </build>
<fork>false</fork>
表示 Maven 使用自身的 JVM 虚拟机运行插件, 而 <fork>true</fork>
则告知 Maven 启动一个新的 JVM 虚拟机进程运行插件. 使用 spring-boot-devtools 模块时需要特定 JVM 配置来运行, 所以需要创建新的 JVM 虚拟机进程来运行. 所以通常使用 spring-boot-devtools 热部署时, 需要在 spring-boot-maven-plugin 插件上会加上 fork=true
<layout>ZIP</layout>
MANIFEST.MF 文件中 Main-Class 是 PropertiesLauncher, 就是 spring-boot-maven-plugin 插件配置 <layout>ZIP</layout>
的结果
- layout:
- JAR,即通常的可执行jar
- Main-Class: org.springframework.boot.loader.JarLauncher
- WAR,即通常的可执行war,需要的servlet容器依赖位于WEB-INF/lib-provided
- Main-Class: org.springframework.boot.loader.warLauncher
- ZIP,即DIR,类似于JAR
- Main-Class: org.springframework.boot.loader.PropertiesLauncher
- MODULE,将所有的依赖库打包(scope为provided的除外),但是不打包Spring Boot的任何Launcher
- NONE,将所有的依赖库打包,但是不打包Spring Boot的任何Launcher
- 此外
<classifier>suffix</classifier>
project-1.1.1-suffix 与 mvn package 所打成的 jar 进行区分 - mvn package 打包时使用 maven-jar-plugin 插件执行 package 命令, 生成的 jar 不包含依赖, 不可以执行但可以作为依赖引用
- 使用 spring-boot-maven-plugin 插件打包将 mvn package 生成的软件包重命名为了 *.original
Gradle thin jar
task clearJar(type: Delete) { delete "$buildDir/libs/lib" } // 将依赖包复制到lib目录 task copyJar(type: Copy, dependsOn: 'clearJar') { into "$buildDir/libs/lib" from configurations.runtime // from configurations.compileClasspath } bootJar { // mainClassName = '' // 例外所有的jar excludes = ["*.jar"] // lib目录的清除和复制任务 dependsOn clearJar dependsOn copyJar // 指定依赖包的路径, 无需 java.ext.dir 或 loader.path 参数 manifest { attributes "Manifest-Version": 1.0, 'Class-Path': configurations.compileClasspath.files.collect { "lib/$it.name" }.join(' ') } }
需要把 dependencies 放到了 bootJar{} 之前
调用 bootJar 打包
运行的时候也不需要指定 -Djava.ext.dirs=./lib 或 -Dloader.path=./lib 了, 将 lib 目录放在 jar 包同级目录下, 直接 -jar运行就可以了
# java -Djava.ext.dirs=./lib -jar bootrun.jar java -jar bootrun.jar
loader.path
loader.path 是 Spring 提供的配置参数
可以使用 --classpath / -cp 指定类加载的路径,但 classpath 的生效是有条件的
# 运行 class 生效 java -cp .;lib/x.jar Test # 运行 jar 失效 java -cp lib/x.jar -jar app.jar
使用 java -jar boot.jar
时 (此时 -cp 无效), 可以使用 loader.path
指定类加载路径加载其他 jar, loader.path
实现了 classpath
的功能
但 loader.path 生效是有条件的
当 MANIFEST.MF 的 Main-Class 为:
- PropertiesLauncher (额外配置) 生效
- JarLauncher (默认配置) 失效 (启动会快一些)
为了使用 loader.path,需要把 jar 包的 Main-Class 配置为 PropertiesLauncher,在 build.gradle 中如下配置,可参考 Using the PropertiesLauncher
bootJar { manifest { attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher' } }
So by adding all the needed classpaths to the loader.path variable, spring will be able to boostrap the application. (details)
到此这篇关于SpringBoot 项目瘦身(maven/gradle)的文章就介绍到这了,更多相关SpringBoot 瘦身maven/gradle内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
相关文章
Maven依赖中scope的runtime和provied的区别及说明
这篇文章主要介绍了Maven依赖中scope的runtime和provied的区别及说明,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2023-11-11一小时迅速入门Mybatis之实体类别名与多参数 动态SQL
这篇文章主要介绍了一小时迅速入门Mybatis之实体类别名与多参数 动态SQL,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下2021-09-09spring cloud feign不支持@RequestBody+ RequestMethod.GET报错的解决方法
这篇文章主要介绍了spring cloud feign不支持@RequestBody+ RequestMethod.GET报错的解决方法,需要的朋友可以参考下2018-01-01Java中Elasticsearch 实现分页方式(三种方式)
Elasticsearch是用Java语言开发的,并作为Apache许可条款下的开放源码发布,是一种流行的企业级搜索引擎,这篇文章主要介绍了Elasticsearch实现分页的3种方式,需要的朋友可以参考下2022-07-07
最新评论