SpringBoot 项目瘦身maven/gradle详解
作者:howeres
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内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!