spring-boot-thin-launcher插件分离jar包的依赖和配置方式
spring-boot-thin-launcher插件分离jar包的依赖和配置
Spring Boot项目可以通过spring-boot-maven-plugin插件打包生成一个可执行的jar包,这样可以脱离web容器(例如tomcat)直接运行。
但默认情况下spring-boot-maven-plugin打出来的包是一个fat jar,即将所有的依赖全部打进了jar包当中,这样的jar包体积很大,每次更新系统的时候都需要完整替换整个jar包(本地还好,如果是云服务器,网速慢了每次上传文件都想砸电脑π__π)。
此外,系统切换环境时,也同时需要切换配置参数,虽然可以使用配置中心或者利用命令行参数修改配置,但有时候也免不了直接需要修改配置文件,这样的话就有必要将配置文件从jar包中分离出来,单独存放。
Spring社区大概也考虑到了部分开发者有这样的需求,所以提供了spring-boot-thin-launcher这个插件用来将项目的依赖和配置从jar包中分离出去。
这个插件虽然是放到spring-projects-experimental(意思就是实验性质的项目)当中的,但从我使用的经验来看应该是比较稳定的,能够满足绝大部分场景的需求。
废话少说,还是先上代码吧
<build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>${java.version}</source> <target>${java.version}</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <configuration> <!--项目的执行入口--> <mainClass>com.example.Application</mainClass> </configuration> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> <dependencies> <dependency> <groupId>org.springframework.boot.experimental</groupId> <artifactId>spring-boot-thin-layout</artifactId> <version>1.0.12.RELEASE</version> </dependency> </dependencies> </plugin> <plugin> <groupId>org.springframework.boot.experimental</groupId> <artifactId>spring-boot-thin-maven-plugin</artifactId> <version>1.0.12.RELEASE</version> <executions> <execution> <!--在编译时下载依赖包 --> <id>resolve</id> <goals> <goal>resolve</goal> </goals> <inherited>false</inherited> </execution> </executions> </plugin> <!--移动配置文件到外部文件夹--> <plugin> <artifactId>maven-antrun-plugin</artifactId> <executions> <execution> <phase>compile</phase> <goals> <goal>run</goal> </goals> <configuration> <tasks> <move file="${project.build.directory}/classes/application.yml" todir="${project.build.directory}/thin/root/config"/> <copy todir="${project.build.directory}/thin/root/"> <fileset dir="${basedir}/bin"/> </copy> </tasks> </configuration> </execution> </executions> </plugin> </plugins> </build>
在maven-antrun-plugin中可以根据需要定义一些额外的任务,比如移动其它的配置文件,或者将外部的一些文件加入到项目目录中(比如执行脚本等)。
这样配置后,
打包以后的target目录大概是这样的
其中thin目录下面就可以作为整个项目的部署目录了,config是配置文件的存放目录,respository下面是所有的依赖包,backend-2.0.jar中仅包含了项目自身的资源,体积比之前小太多了。
##运行原理那为什么执行时,系统知道自动去外部加载依赖和配置呢?
这个问题需要首先了解打包后的结构,把backend-2.0.jar解压之后,会发现除了我们自己的类和资源以外,还多了一个类:org.springframework.boot.loader.wrapper.ThinJarWrapper,其实我们在运行项目时,这个类才是真正的项目入口,它会在默认位置查找项目相关的依赖,如果没有找到,甚至还会从指定的maven仓库中直接下载,所以启动时系统能够识别到外部的依赖包。
至于外部配置,是因为Spring Boot框架在读取配置文件时,会默认读取几个目录下的配置文件,其中优先级最高的就是当前目录下的config目录(所以config目录的名字不能改成其它的)。
执行jar包的时候需要注意,要额外添加一个参数来指定依赖包所在的仓库位置(在我们的配置中就在jar包的当前文件夹)
例如:-Dthin.root=. 默认的位置是${user.home}/.m2,如果仓库中没有需要的依赖,启动jar包时还会自动连接远程仓库进行下载,导致启动时间非常长,这一点需要注意。
spring-boot-thin-launcher还有很多可配置的参数,具体可以到 官网 上自行查看。
附上一个通用的spring-boot-thin-launcher打包文件的启动脚本
#!/bin/bash #这里指定需要运行的jar包的名字 APP_NAME="your-jar-name.jar" JVM_ARGS="-Xms512M -Xmx2048M -XX:+UseG1GC -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/log/heap.hprof" THIN_ARGS="-Dthin.root=. -Dthin.offline=true" #使用说明,用来提示输入参数 usage() { echo "Usage: sh 执行脚本.sh [start|stop|restart|status|run]" exit 1 } #检查程序是否在运行 is_exist(){ pid=`ps -ef|grep $APP_NAME|grep -v grep|awk '{print $2}' ` #如果不存在返回1,存在返回0 if [ -z "${pid}" ]; then return 1 else return 0 fi } #后台启动 start(){ is_exist if [ $? -eq "0" ]; then echo "${APP_NAME} is already running. pid=${pid} ." else echo "${APP_NAME} running with args: nohup java $THIN_ARGS -jar $JVM_ARGS $APP_NAME " nohup java $THIN_ARGS -jar $JVM_ARGS $APP_NAME >> catalina.out 2>&1 & fi } #前台启动 run(){ is_exist if [ $? -eq "0" ]; then echo "${APP_NAME} is already running. pid=${pid} ." else echo "${APP_NAME} running with args: java $THIN_ARGS -jar $JVM_ARGS $APP_NAME" java $THIN_ARGS -jar $JVM_ARGS $APP_NAME fi } #停止方法 stop(){ is_exist if [ $? -eq "0" ]; then kill -9 $pid else echo "${APP_NAME} is not running" fi } #输出运行状态 status(){ is_exist if [ $? -eq "0" ]; then echo "${APP_NAME} is running. Pid is ${pid}" else echo "${APP_NAME} is NOT running." fi } #重启 restart(){ stop start } #根据输入参数,选择执行对应方法,不输入则执行使用说明 case "$1" in "start") start ;; "run") run ;; "stop") stop ;; "status") status ;; "restart") restart ;; *) usage ;; esac
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
相关文章
Eclipse添加xml文件提示及Hibernate配置学习
文件提示功能在开发过程中很实用的,本文实现了一个Eclipse添加xml文件提示,感兴趣的朋友可以了解下啊,希望本文对你有所帮助2013-01-01springboot如何读取配置文件(application.yml)中的属性值
本篇文章主要介绍了springboot如何读取配置文件(application.yml)中的属性值,具有一定的参考价值,有兴趣的小伙伴可以了解一下2017-04-04关于BufferedReader的read()和readLine()的区别
这篇文章主要介绍了关于BufferedReader的read()和readLine()的区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教2021-12-12
最新评论