目录
- 前言
- 步骤
- 选择合适的JDK版本
- 从maven切换到gradle
- 运行thinjar
- 问题
- 参考
前言
线上的SpringBoot应用已经达到350M,每次更新都花费半小时,虽然每天只更新一次。于是决定来一次瘦身。但是为了更方便的打包,例如既能打出fatjar,也能打出thinjar,同时也能根据需要打出war包,决定将构建脚本迁移到gradle。
2003年,我完成了手工构建(JBuilder2005)到ant自动构建的转变,2012年,完成了ant到maven的转变,后来,除了android应用外,Spring应用我都是才有maven构建,一直也很平稳,没给我惹过乱子。记得2012年采用maven构建时,IBM团队的一个老外坚决反对,他选用公司内部的一套ant框架。为何?人总是习惯使用用熟了的东西。
步骤
选择合适的JDK版本
目前JDK8, JDK11, JDK17是三个重要的版本。经过折腾,我选用了JDK11这个版本。不同版本的热部署方案有差异。
从maven切换到gradle
先执行
gradle init
即可生成build.gradle文件,里面包含了依赖,它将pom.xml的依赖转换成了gradle依赖。这个很不错。否则手工去写依赖就比较痛苦。
// 将依赖包复制到lib目录
task copyJar(type: Copy) {// 清除现有的lib目录delete "$buildDir/libs/lib"
// //需要复制的文件from configurations.compileClasspathinto "$buildDir/libs/lib"
}// 拷贝配置文件
task copyConfigFile(type: Copy) {// 清除现有的配置目录
// delete "$buildDir\\libs\\config"
// from('src/main/resources')
// into 'build/libs/config'
}bootJar {launchScript()// 例外所有的jarexcludes = ["*.jar", "fonts/*"]// lib目录的清除和复制任务dependsOn copyJardependsOn copyConfigFile// 指定依赖包的路径manifest {attributes 'Main-Class': 'org.springframework.boot.loader.PropertiesLauncher'attributes 'Start-Class': 'com.icool.CmsApplication'
// attributes "Manifest-Version": 1.0,
// 'Class-Path': project.configurations.compileClasspath.files.collect { "lib/$it.name" }.join(' ')}
}
这里两个注意点:
- excludes把fatjar下的BOOT/lib的文件都排除掉,放到外面去,这是瘦身最主要的步骤
- 采用PropertiesLauncher启动应用,不能采用缺省的JarLauncher。PropertiesLauncher支持-Dloader.path选项,这样就可以加载外部的jar了。
PropertiesLauncher允许通过配置loader.path使得jar包可以去加载外部的jar。而JarLauncher只能处理jar-in-jar这种模式。通常来说使用JarLauncher作为Main-Class被称为fat-jar,而PropertiesLauncher则可以将fat-jar变成thin-jar,之所以可以这样做,正是应为PropertiesLauncher使得jar包可以去加载外部的jar。
运行thinjar
瘦身后的jar运行方式:
java -Dloader.path=path/to/lib -Dspring.profiles.active=prod -jar cms-0.0.1-SNAPSHOT.jar
也可以:
java -cp bootApp.jar -Dloader.main=com.xxx.DemoApplication org.springframework.boot.loader.PropertiesLauncher
问题
迁移后,发现热部署不起作用了,一堆的Spring Bean创建问题,后来发现是自己安装了HotSwapAgent这个插件导致的。
参考
- github.com/spring-projects-experimental/spring-boot-thin-launcher