基于gradle的java项目自定义构建

2020-06-09  本文已影响0人  飞行员舒克_ed03

项目或工作中存在的问题

背景技术及术语解释

Gradle 构建已经相当的普遍,目前使用的spring框架已使用gradle构建。
gradle 是用groovy(Groovy是一种基于JVM的动态语言)编写工具。可以帮助团队构建,持续集成,快速交付的工具,是一种DSL,即Domain Specific Language,领域相关语言,有自己特有的术语。

Gradle特点:

本方案技术详细描述

案例1:

案例说明: 项目源代码(如图1所示)下有个tools文件夹,tools文件夹下有1个项目使用说明和项目启动脚本,现需要将项目打包成图2的形式,即将项目打包成jar包,并将tools下的内容构建于jar文件同一目录下,方便项目启动;并且要将src/main/resources/下的application.yml打包的时候复制到config目录下;并且为了传输方便,还得将整个项目打包成zip包。目前maven除了自己开发插件实现外,无法实现该功能,但是通过gradle可以轻松的实现。

方式一:在项目根目录的build.gradle文件内加入如下代码。
`task copyReadme(type:  Copy){`
 `from ('tools')`
 `into libsDir`
`}`

`task copyResources(type:  Copy){`
 `from ('src/main/resources/application.yml')`
`into "$libsDir/config/"`
`}`

 `task unzip(type:  Copy)  {`
`println "==============================>unzip"`
`into "$buildDir/classes/java/main"`
 `}`

`task zip(type:  Zip, dependsOn: build){`
`into ('event-simulation'){`
`from libsDir`
`}`
`}`

 `build.finalizedBy(copyReadme,copyResources)`

代码解释及原理说明:gradle构建有个接口是finalizedBy,作用是在于在构建结束时调用自定义的任务。
所以我们自定义2个task,task的格式是闭包。
闭包在groovy中是一种类型,类似与java中的lambda表达式和接口,具体请查阅groovy语言。
第一个task是复制脚本,任务的类型是复制type: Copy, 从tools文件夹复制到编译目录下的lib文件夹下。
第二个task是将application.yml文件从src/main/resources复制到编译目录下的lib文件夹下的config目录下。如果没有该目录会自动创建。
然后我们使用finalizedBy去调用他们。
最后我们创建第三个task,我们命名为zip,任务类型是Zip,dependsOn是依赖于构建,内容是将lib文件夹下的内容打包成event-simulation.zip。
那么我们如何运行呢?在项目根目录下我们运行

`gradle clean zip`

因为我们声明zip依赖与build,所以先执行build编译项目,在项目编译结束时调用上述2个方法,最后调用我们的zip方法打包。
但这种方法还是有点繁琐,在这里列举希望大家有个基本的概念,我们来看第二种实现方式。我们在第二种实现中加入新的功能:将项目的名称和版本号到我们的说明文档中。

方式二:

`apply plugin:  'distribution'`
`distributions {`
 `main {`
`archivesBaseName = baseName`
`contents {`
`from (libsDir,'tools')`
`rename (archivesBaseName +  '-'  + version, archivesBaseName)`
`into ('config')  {`
`from ('src/main/resources/application.yml')`
 `}`
 `eachFile { file ->`
`if  (file.name.startsWith('readme'))  {`
`filter{ line -> line.contains('${version}')  ? line.replace('${version}', version)  : line}`
 `}`
`}`
 `}`
`}`
`}`

方式二的目标是一样的,我们使用gradle内置的插件完成,插件的作用是在编译输出文件夹下创建distributions文件夹,并将编译后的内容进行打包成zip文件。
首先,声明使用插件apply plugin: 'distribution'
然后,我们使用插件的固定格式来定义,步骤如下:
第一步,声明变量archivesBaseName,即压缩包的名称为项目名称;
第二步,复制libsDir下的文件(编译好的jar包)和tools下的文件(脚本和readme)复制到根目录;
第三步,重命名archivesBaseName-version为压缩包名称;
第四步,将application.yml文件从src/main/resources/目录下复制到根目录的config文件夹下;
第五步,打包时过滤文件,将readme文件中含义变量${version}替换为版本目前项目中的版本号。
定义好打包内容后,最后我们运行:

 gradle clean distributions

最终得到图三的zip包,这样就可以发给第三方使用了。

案例2:

本案例的目标是因为开发文件和生成环境文件经常产生冲突,导致生成环境打包内容不符合生成环境的要求。具体如下。
原spring-boot项目在开发中使用application-dev.yml的配置文件,是否启用该文件的通过application.yml的

 `spring:`
`prifiles:`
`active: dev`

来控制,当application.yml有变动时,经常会误将改配置变更导致失败,所以我们从技术手段上防止该事情的方式。
首先,我们创建application-prod.yml作为生产环境的配置文件;
然后,我们在生产环境构建时,自动的去修改这里的配置为prod,这样可以保证每次构建都是启用application-prod.yml这个文件,
接着,由于日志文件在开发可生产环境中配置也不一致,我们一并修改。
最后,我们在构建时将开发配置文件排除在生产环境的包外。
我们在项目根目录的build.gradle加入如下代码。

ext.PROD =  'prod'
processResources {
  filteringCharset =  'UTF-8'
  String buildType = project.getProperties().get('buildType')
  if  (buildType == PROD){
    eachFile {file ->
    if(file.name ==  'application.yml')  {
      filter { line -> line.contains('active')  ? line.replace('dev','prod')  : line }
    }
  if(file.name ==  'logback-spring.xml')  {
  filter { line -> line.contains('logs')  ? line.replace('logs','${catalina.base}/logs')  : line }
}

}
exclude 'application-dev.yml'
}
}

首先,我们新建一个变量,变量名称是PROD,当构建时,如果改变量名称为prod时,按生产环境的方式构建。
然后,我们声明查询的字符集是UTF-8;
接着,从命令行获取buildType参数,当此参数等于prod时,执行生产环境构建,
第一步,在过滤文件时获取名称为application.yml,并修改配置,
第二步,在过滤文件时获取名称为logback-spring.xml的日志配置文件,替换其中的变量,
第三步,排除application-dev.yml
最后,我们在生产环境的自动化构建时,执行如下命令

1.  `gradle clean build -x test -P buildType=prod`

到此我们将生成环境和开发环境进行了彻底的分割,再也不用担心误传导致的构建失败了。

上一篇 下一篇

猜你喜欢

热点阅读