springboot项目如何打包成.sh脚本形式运行|assemly插件打包自定义脚本参数

news/2024/5/20 2:32:10/文章来源:https://blog.csdn.net/qq_24950043/article/details/126555657

0. 引言

springboot作为目前主流的java开发框架,因为便捷和易上手的特性,深受开发者欢迎。springboot默认以jar包形式,通过java -jar指令运行

但这样的启动方式实际上不是很友好,我们常常看到各类组建通过bin目录下的start.sh脚本进行启动,我们可以在.sh脚本中书写自定义各类启动参数。这样的方式更加友好,那么我们的springboot项目可不可以打包成这样的形式启动呢?

当然可以,今天我们就来看如何实现

1. assembly-plugin插件

assembly是一个maven插件,专门用于maven项目打包。它的作用就是可以将项目打包成一个可以通过脚本文件启动的项目包

其打包后的项目文件结构如下:

bin 项目启动/停止/重启等脚本文件目录
conf 配置文件目录
lib 依赖包目录

assembly插件需要配置一个.xml配置文件来指定打包设置。该文件常见的标签配置如下:

  • id: 标识符,添加到打包文件名称的后缀符
    如果设置为${project.version}则会将项目版本号添加到打包文件名中
  • formats:打包格式,支持zip、tar、tar.gz (or tgz)、tar.bz2 (or tbz2)、jar、dir、war等格式,可以同时指定多种打包形式,通过format标签指定
<formats><format>tar.gz</format><format>jar</format>
</formats>
  • includeBaseDirectory 是否包含打包层目录,当设置false时,所有文件直接打包到根目录下;为true时,打包到${artifactId}目录下
  • dependencySets 设置项目依赖包打包的目录
  • fileSets 设置要包含的文件集,可以定义多个fileSet,单个fileSet标签中又包含如下子标签
    directory:要打包的文件夹
    outputDirectory:打包出来的文件夹,比如为bin,则表示将directory文件夹下的文本打包到bin目录下
    includes: 指定要包含(include)或排除(exclude)的打包文件
    fileMode:指定文件权限,权限的指定参考linux系统文件权限,比较常用的0755,0644。我们在文末单独讲解
    directoryMode:指定目录权限
<fileSet><directory>src/main/assembly/bin</directory><outputDirectory>bin</outputDirectory><includes><include>start.sh</include><include>stop.sh</include></includes><fileMode>0755</fileMode>
</fileSet>

2. 实操

1、首先我们先创建一个springboot项目assembly-plugin-demo,并且引入spring web依赖,模拟一个web项目

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>

2、创建一个HelloController,并书写一个简单的接口,用于模拟接口

/*** @author benjamin_5* @Description* @date 2022/8/27*/
@RestController
public class HelloController {@GetMapping("/hello")public String hello(){return "hello~~";}}

3、在项目src/main下创建bin目录,并声明启动/停止/重启脚本

启动脚本 start.sh

#!/usr/bin/env bash#source $(dirname $0)/../../env.sh
# 进入当前文件目录
cd `dirname $0`
# 返回上一级
cd ..# jar包名称
#SERVER_JAR="$SERVER_NAME-$PROJECT_VERSION.jar"
SERVER_JAR="assembly_plugin_demo-0.0.1-SNAPSHOT.jar"
BASE_DIR=`pwd`# 获取java路径
if [ "$JAVA_HOME" != "" ]; thenJAVA="$JAVA_HOME/bin/java"
elseJAVA=java
fi# 指定日志输出路径
LOGS_DIR=""
if [ -n "$LOGS_FILE" ]; thenLOGS_DIR=`dirname $LOGS_FILE`
elseLOGS_DIR=$BASE_DIR/logs
fi
if [ ! -d $LOGS_DIR ]; thenmkdir $LOGS_DIR
fi
STDOUT_FILE=$LOGS_DIR/stdout.log# 设置jvm参数
JAVA_OPTS="-server -Xms1G -Xmx2G -Xmn256m -Xss1m \
-XX:SurvivorRatio=4 -XX:+UseConcMarkSweepGC -XX:+UseCMSCompactAtFullCollection \
-XX:CMSInitiatingOccupancyFraction=60 -XX:+PrintGCDateStamps \
-XX:+PrintGCDetails -Xloggc:$LOGS_DIR/gc.log"# 如果项目已经启动则之前停止项目
echo -n "Starting server ..."PID=$(ps -ef | grep $SERVER_JAR | grep -v grep |awk '{print $2}')
if [ -z "$PID" ]; thenecho Application is already stopped
elseecho kill $PIDkill -9 $PID
fi# 以指定参数启动项目
nohup $JAVA $JAVA_OPTS $JAVA_DEBUG_OPT -jar lib/$SERVER_JAR > $STDOUT_FILE 2>&1 &if [ $? -eq 0 ];then# echo -n $! > "$PIDFILE"if [ $? -eq 0 ]thensleep 1echo STARTEDelseecho FAILED TO WRITE PIDexit 1fi
elseecho SERVER DID NOT STARTexit 1
fiPID_NOW=`ps -ef | grep java | grep -v grep | grep "$SERVER_JAR" | awk '{print $2}'`
# 打印参数
echo "进程ID: $PID_NOW"
echo "输出日志:$STDOUT_FILE"

停止脚本 stop.sh

#!/usr/bin/env bash# jar包名称
SERVER_JAR="assembly_plugin_demo-0.0.1-SNAPSHOT.jar"# 停止项目
echo -n "Stopping server ..."PID=$(ps -ef | grep $SERVER_JAR | grep -v grep |awk '{print $2}')
if [ -z "$PID" ]; thenecho Application is already stopped
elseecho kill $PIDkill -9 $PID
fi
exit 0

4、然后我们在项目的src/main目录下创建一个assembly目录,并且创建一个assembly插件的配置文件assembly.xml

我们需要在assembly.xml配置文件中申明bin,conf,lib三个路径

<assembly><id>assembly</id><formats><format>tar.gz</format></formats><includeBaseDirectory>true</includeBaseDirectory><fileSets><fileSet><directory>src/main/assembly/bin</directory><outputDirectory>bin</outputDirectory><fileMode>0755</fileMode></fileSet><fileSet><directory>src/main/resources</directory><outputDirectory>conf</outputDirectory><fileMode>0644</fileMode></fileSet></fileSets><dependencySets><dependencySet><outputDirectory>lib</outputDirectory></dependencySet></dependencySets>
</assembly>

在这里插入图片描述

5、其次我们在pom.xml中引入assembly-plugin插件

<plugin><artifactId>maven-assembly-plugin</artifactId><configuration><descriptor>src/main/assembly/assembly.xml</descriptor></configuration><executions><execution><id>make-assembly</id><phase>package</phase><goals><goal>single</goal></goals></execution></executions>
</plugin>

6、重新加载pom文件,下载assembly插件

7、执行打包指令

在这里插入图片描述

出现BUILD SUCCESS说明打包成功

在这里插入图片描述

8、打包文件输出在target目录下,如果有指定输出目录,则在输出目录中查找

在这里插入图片描述

9、我们将打包出来的’.tar.gz’压缩包文件解压,可以看到其结构就是我们上述指定的bin、conf、lib目录

在这里插入图片描述

10、进入bin目录,执行start.sh指令启动项目

./start.sh

在这里插入图片描述

11、我们已经将输出内容指定到logs目录下的stdout.log,我们可以通过该日志查看启动明细

如果启动失败,也可以通过该日志文件查看报错明细。同时也指定了gc日志gc.log,可以通过该文件查看gc详情

在这里插入图片描述
12、从上述日志看启动成功了,我们通过访问之前定义的接口来测试

可以看到正常输出了接口数据,证明我们打包并启动成功了

在这里插入图片描述

如上,我们的springboot就成功打包成了bin目录启动形式。

2.1 优化【未完善】

上述打包程序并不是最佳的,因为我们的项目的jar包名称是在start.sh脚本中写死的,如果版本升级,或者复用到其他模块中时,就需要修改脚本了,非常的不方便

所以我们做出优化,希望能够自动获取这个jar包名称

可以看到我们的jar包名称是:assembly_plugin_demo-0.0.1-SNAPSHOT.jar

这个名称由两部分组成:服务名,版本号

于是我们就要想办法获取这两个属性

1、首先服务名直接在application.properties配置文件中通过spring.application.name属性获取。

2、配置文件是会一起打包到conf文件夹下的,但我们怎么在shell脚本中获取配置文件中的指定配置项呢?

答案是可以通过sed指令,如下所示

PROJECT_VERSION=`sed '/^project.version=/!d;s/.*=//' conf/application.properties`

3、其次就是版本号,我们知道版本号是定义在pom.xml文件中的,打包后是没有pom文件的,那么我们的思路就是在application.properties配置文件中获取到版本号

这里就要考验大家的springboot知识积累了,如何在配置文件中获取到pom属性呢?

4、首先我们要在pom.xml文件中,添加resource标签,设置filtering=true,让配置文件可以读取pom属性

<build><resources><resource><directory>src/main/resources</directory><filtering>true</filtering></resource></resources>
</build>

5、设置完成后记得重新加载pom文件!!!

6、然后在application,properties配置文件中通过@xxx@获取pom属性"project.version"

application.version=@project.version@

7、在start.sh脚本中再声明版本号和jar包名变量

PROJECT_VERSION=`sed '/^application.version=/!d;s/.*=//' conf/application.properties`
SERVER_JAR="$SERVER_NAME-$PROJECT_VERSION.jar"

8、重新打包即可,stop.sh脚本中处理类似

9、这里存在一个问题尚未解决,上述说的@xxx@的方式读取pom属性,在idea中打包,可以看到本身的打包插件已经加载了pom中的属性,如下图

在这里插入图片描述

但是assembly插件打包的conf目录中的配置文件中却没能加载pom的值,初步怀疑是加载顺序的问题,仍在研究中,这里也抛出问题点,大家一起讨论解决。有思路的同学,可以留言讨论

在这里插入图片描述

演示代码见文末

3. 补充内容

fileMode/directoryMode权限

assembly中的权限表示与linux系统一致,通过4位数值表示权限

其中第一位0表示采用十进制,第二位表示用户权限,第三位组用户权限,第四位表示其他用户权限,而十进制表示的权限等级如下:

十进制linux权限说明
0无任何权限
1–x执行权限
2–w可写权限
3-wx可写、执行权限
4r–只读权限
5r-x可读、可执行权限
6rw-读写权限
7rwx全部权限

则0755表示用户具有读/写/执行权限,组用户和其它用户具有读写权限;0644表示用户具有读写权限,组用户和其他用户具有只读权限

4. 演示源码

git地址

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.luyixian.cn/news_show_5128.aspx

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阿里、腾讯、百度大厂的程序员编程指南规范

众所周知&#xff0c;现在软件行业不仅要求功能完成&#xff0c;对代码规范也是要求非常高的。一个编程规范不仅是代码美观、易读&#xff0c;在调试bug、程序安全等方面都是有影响的。比如&#xff1a;代码中的魔法数字&#xff0c;要求提取枚举、SQL语句要求不能采用拼接方式…

我开发了一个下载器 带宽拉满

大家好&#xff0c;我是 jonssonyan&#xff0c;一个痴迷软件技术的人。今天和大家分享一个我之前开发的 PC 端下载器。 准确的说是一款基于 AriaNg 和 Aria2 的 PC 端下载器。目前只支持 Windows 平台&#xff0c;我给它取名叫Aria2-X&#xff0c;并且将代码开源在 GitHub 上…

YOLOv7改进之二十五:引入Swin Transformer

​前 言&#xff1a;作为当前先进的深度学习目标检测算法YOLOv7&#xff0c;已经集合了大量的trick&#xff0c;但是还是有提高和改进的空间&#xff0c;针对具体应用场景下的检测难点&#xff0c;可以不同的改进方法。此后的系列文章&#xff0c;将重点对YOLOv7的如何改进进行…

终于拿到了爆火全网的进一线大厂程序员必看的1700道java面试题

爆火全网的进一线大厂程序员必看的1700道java面试题到底有多牛&#xff1f; 牛不牛不敢说&#xff0c;但是有好多程序员是靠这一套1700道高频面试题&#xff0c;顺利收到很多大厂offer&#xff01; 以至于&#xff0c;到现在为止&#xff0c;大厂都开始按照这一套1700道面试题…

北京十大靠谱律师事务所排名(口碑榜单)

律师行业很多人并不太了解&#xff0c;其实简单的案件一般不需要律师有丰富的经验积累&#xff0c;因此委托入行不久的年轻律师&#xff0c;他们能花更多时间去帮你处理&#xff0c;态度好&#xff0c;更重要的是收费低。 复杂的或者涉及金额特别大的案子委托资深律师。当然不是…

【Lua 入门基础篇(十)】文件I/O

文章目录一、文件 I/O二、简单模式1. io.lines([filename])三、完全模式1. file:lines()一、文件 I/O Lua I/O 库用于读取和处理文件。分为简单模式、完全模式。 简单模式&#xff08;simple model&#xff09;&#xff1a;拥有一个当前输入文件和一个当前输出文件&#xff0c…

倾向得分匹配PSM案例分析

倾向得分匹配(PSM)&#xff0c;是一种模仿RCT随机对照试验随机化分组&#xff0c;提高组间均衡性&#xff0c;进而达到降低混杂因素影响目的一种数据处理策略。PSM在计量研究&#xff0c;临床医学等领域有着广泛的应用。 1.案例背景与分析策略 1.1 案例背景介绍 某企业想评价…

IDEA编译项目找不到符号

问题描述 场景: 某个bean添加了一个字段; idea使用Git拉取代码后,新建分支提交,然后修改再切换其他分支,发生了代码冲突; 然后解决代码冲突,开始编译项目,报错找不到符号. 问题分析 1.查看控制台日志输出,找报错代码行。 2.lombok插件注解未生效。 3.编码问题; 4.jdk…

vue基础语法(上)

目录 一、插值 1、文本 2、html 3、属性 4、表达式 5、class绑定 6、style绑定 二、指令 1、核心指令 注&#xff1a;v-show和v-if区别 三、过滤器 1、全局过滤器 2、局部过滤器 四、计算属性与监听属性 1、计算属性 2、监听属性 3、计算属性和监听属性的区别 …

李沐d2l(十一)--锚框

文章目录一、概念二、代码1 生成锚框2 IoU(交互比)3 将真实边界框分配给锚框4 标记类和偏移5 应用逆偏移变换来返回预测的边界框坐标6 nms7 将非极大值抑制应用于预测边界框一、概念 在目标检测算法中&#xff0c;通常会在输入图像中采样大量的区域&#xff08;生成多个边缘框&…

ELASTICSEARCH快速入门

1. ELASTICSEARCH 1、安装elastic searchdokcer中安装elastic search (1)下载ealastic search和kibana docker pull elasticsearch:7.6.2docker pull kibana:7.6.2 (2)配置 mkdir -p /mydata/elasticsearch/config 创建目录mkdir -p /mydata/elasticsearch/dataecho "…

fastapi+mongo+qlib:体系化构建AI量化投研平台

百天计划之第34篇&#xff0c;关于“AI量化投资研究平台”建设。 从今天开始要开始一条主线——就是开始搭建整个投研平台。 如果说8月开始是知识点的梳理&#xff0c;一些基础技术的准备&#xff08;以qlib和机器学习为核心&#xff09;&#xff0c;9月开始重点是“以解决真…

.NET Entity FrameWork 总结 ,在项目中用处个人感觉不大。适合初级用用,不涉及到与数据库通信。

更新数据 第一种&#xff1a; 先从数据库中取出数据&#xff0c;然后再更新字段。效率较低&#xff0c;需要2次数据库操作&#xff1b; Entities&#xff1a;就是EF实体数据模型 using (var db new Entities()) { var data db.Member.Find(5); data.Name “new name”; db.…

基于Springboot+vue的玩具销售商城网站 elementui

爱玩儿是所有孩子的天性。尤其是在婴幼儿阶段。选择一个好的玩具&#xff0c;不仅能够让孩子玩儿的开心&#xff0c;而且有助于孩子智力的开发。很多家长在选择玩具的时候&#xff0c;不知道选择什么样的玩具。且当前玩具市场的玩具鱼目混杂&#xff0c;种类繁多&#xff0c;而…

cmake和makefile区别和cmake指定编译器(cmake -G)

一 cmake和makefile区别 要说明区别,我们先要区分下面三类工具: 1.项目构建生成工具 首先cmake是项目构建生成工具,cmake的代码可以与平台系统和编译器无关。类似cmake的工具还有autotools、qmake、GN,其中qmake已基本由cmake替代。cmake下载地址 cmake.org.cn 也就是说cma…

1.初识jQuery

jQuery是JS的库&#xff0c;封装了原生JS的一些DOM方法&#xff0c;使JS用起来更方便 目录 1 下载jQuery 2 jQuery的基本使用方式 3 jQuery入口函数 1 下载jQuery jQuery官网 jQuery 点击这里进入下载页面&#xff0c;我当前的版本为 3.6.1&#xff0c;如果你想下载之…

2022极端高温!人工智能如何预测森林火灾?| 万物AI

&#x1f4a1; 作者&#xff1a;ShowMeAI编辑部 &#x1f4e2; 声明&#xff1a;版权所有&#xff0c;转载请联系平台与作者并注明出处 &#x1f4e2; 收藏ShowMeAI查看更多精彩内容 8月21日晚&#xff0c;重庆北碚区山火一路向国家级自然保护区缙云山方向蔓延。为守护家园&…

LabVIEW通过网络传输数据

LabVIEW通过网络传输数据 选择应用程序的联网功能时&#xff0c;最重要的因素是应用程序使用的通信模型。不同的通信模型具有不同的数据传输要求。下表列出了最常见的几种通信模型以及推荐功能。 通信模型 说明 范例 推荐联网功能 处理数据 传输最新数据&#xff0c;从一…

Vue模块语法上(插值指令过滤器计算属性-监听属性)

文章目录 一、插值 1&#xff09;文本 2&#xff09;html 3&#xff09;属性 4&#xff09;表达式 5&#xff09;class绑定 6&#xff09;style绑定 二、指令 1.v-if|v-else|v-else-if 2.v-show 3.v-for 4.v-bind 5.v-on 6.v-model 三、过滤器 全局过滤器 局部过滤器…

从零开始配置SSH密钥到github

最近电脑新环境&#xff0c;重新配置SSH 密钥链接GitHub 1 git安装 1.1 下载git 在官网下载git.exe 下载地址》 https://github.com/git-for-windows/git/releases/download/v2.37.3.windows.1/Git-2.37.3-64-bit.exe 1.2 安装git 双击运行程序&#xff0c;然后一直下一步…