很多时候我们在打包的时候可能不会使用springboot的默认的打包插件,可能需要手动打包,通常将所依赖的jar和启动应用程序进行分离.为什么这么做呢?
打包分离依赖的jar及配置文件有以下几点好处:
1.项目目录结构更加清晰.
2.版本迭代过程中,只需要更新依赖的jar,而不需要更新全局依赖的jar,尤其是大型项目,打包本来就是一个耗时的工作,如果在将jar上传到服务器,尤其是不在同一局域网下的服务器,可能每次测试或者发布或者修复bug都需要耗费很长的时间.
[1].项目使用gradle进行打包,首先需要添加 id 'application'指定打包程序为一个应用.
plugins {
id 'java'
id 'application'
}
[2].指定配置环境,可以根据不同需求进行定制化打包.
//1.定义配置文件环境 prod|dev|test
def env = "prod"
[3].指定扩展参数,下面会介绍具体在哪里使用.
ext {
//2.指定扩展参数-主类
masterMain = 'com.tony.test.TestSpringBootApplication'
//3.指定启动类配置文件
masterSources = files("$buildDir/resources/main")
}
[4].这里使用到上面的参数,masterMain名称可以自己指定,mainClassName主要是 id 'application'配置的一个参数
//4.gradle关联启动主类,主要是生成的启动脚本中会指定启动的类的路径
mainClassName = masterMain
[5].制作启动脚本
//5.这里是制作启动脚本的io线程
tasks.startScripts {
classpath += files("resource")
doLast {
//针对不同的平台进行不同的包文件格式
def windowsScriptFile = file getWindowsScript()
def unixScriptFile = file getUnixScript()
windowsScriptFile.text = windowsScriptFile.text.replace('$APP_HOME/lib/resource', '$APP_HOME/resource')
unixScriptFile.text = unixScriptFile.text.replace('$APP_HOME/lib/resource', '$APP_HOME/resource')
}
}
[6].将配置文件打包.
//6.最重要的一步,将配置文件分离
distributions {
main {
contents {
into('resource') { //指定需要将配置文件放入的目录
from("src/conf/$env") { //指定当前配置文件所有在目录
include '/**/*' //动态指定需要打包的配置文件 Ant表达式
}
}
}
}
}
[7].使用gradle build -x test进行打包,打包后的项目结构如下:
[8].打包springboot web项目应用注意事项
distributions {
main {
contents {
into('resource') {
from("src/conf/$env") {
include '**/*'
}
}
//需要加上这一行配置,保证webapp下面的文件被打包到springboot配置文件路径中,纯spring boot web应用不用考虑或者前后端分离项目不用考虑.
into('resource/META-INF/resources/') {
from("src/main/webapp") {
include '**/*'
}
}
}
}
}
[9].详细说明下打包后的启动脚本及打包原理
,首先需要介绍下linux pwd 命令:
pwd [选项]
参数:-L
:--logical
,显示当前的路径,有连接文件时,直接显示连接文件的路径,(不加参数时默认此方式)-p
:--physical
,显示当前的路径,有连接文件时,不使用连接路径,直接显示连接文件所指向的文.当包含多层连接文件时,显示连接文件最终指向的文件.
这里可以看到pwd在打包的过程中是为了定位项目的绝对位置.因为我们要做的就是需要将配置文件进行IO操作,也就是移动到我们项目定义好的目录下,这样我们才能读到配置文件并加载.
#这里是启动脚本指定的APP_HOME,也就是应用的目录
APP_HOME="`pwd -P`"
这里是指定程序读取配置文件的位置,根据不同的需求,可以指定相对路径也可以指定绝对路径,当然这里只是做一个参考.
那我们就应该把配置文件打包到相应的目录,文件流完全就可以做到,配置文件主要是一个IO操作,将当前目录下的配置文件写到指定的配置文件下即可.
回到启动脚本程序,继续往下看. 下面指定应用名称 build.gradle文件中指定.
APP_NAME="xxxxxx"
build.gradle中指定jvm调优参数.在文件中指定
applicationDefaultJvmArgs = jvmArgs
task jvmArgTask {
if(env == 'dev'){
jvmArgs=['-Xms2G', '-Xmx2G', '-server', '-XX:+UseG1GC','-XX:+UseStringDeduplication',
'-XX:+UnlockExperimentalVMOptions','-XX:ParallelGCThreads=8','-XX:ConcGCThreads=4',
'-XX:MaxGCPauseMillis=100','-XX:G1NewSizePercent=70','-XX:G1MaxNewSizePercent=80']
}else if(env == 'test') {
jvmArgs=['-Xms6G', '-Xmx6G', '-server', '-XX:+UseG1GC','-XX:+UseStringDeduplication',
'-XX:+UnlockExperimentalVMOptions','-XX:ParallelGCThreads=8','-XX:ConcGCThreads=4',
'-XX:MaxGCPauseMillis=100','-XX:G1NewSizePercent=70','-XX:G1MaxNewSizePercent=80']
}else{
jvmArgs=['-Xms32G', '-Xmx32G', '-server', '-XX:+UseG1GC','-XX:+UseStringDeduplication',
'-XX:+UnlockExperimentalVMOptions','-XX:ParallelGCThreads=8','-XX:ConcGCThreads=4',
'-XX:MaxGCPauseMillis=100','-XX:G1NewSizePercent=70','-XX:G1MaxNewSizePercent=80']
}
}
#启动脚本,jvm参数设置,实际上就是命令行参数
DEFAULT_JVM_OPTS="...."
#所有依赖的jar,指定到classpath,用于启动时,应用类加载器加载,由于太多就不添加了,只列出部分依赖
CLASSPATH=$APP_HOME/lib/merchant-test-1.0-SNAPSHOT.jar:$APP_HOME/lib/netty-1.0.0.jar:$APP_HOME/lib/slf4j-log4j12-1.7.25.jar:$APP_HOME/lib/log4j-1.2.17.jar:$APP_HOME/lib/guava-23.0.jar:$APP_HOME/lib/fastjson-1.2.56.jar
至此基本重要的点都讲到了,其他的一些只是启动脚本对运行环境的设定,不过多讲解.