Gradle的简单使用

417 阅读16分钟

Gradle

一、Gradle是什么?

Gradle是一个开源构建自动化工具,旨在足够灵活地构建几乎任何类型的软件。以下是其一些最重要功能的高级概述:

  • 高性能:Gradle仅运行那些输入或输出发生变化的任务。还可以通过构建缓存来重用以前运行任务的输出,甚至可以通过共享缓存来使用其他计算机的输出。
  • 基于JVM:Gradle运行在JVM上,因此可以使用标准的Java API来写构建逻辑。但Gradle不仅仅支持构建JVM项目,本地类型项目也同样支持。
  • 约定:Gradle和Maven一样,有一些约定俗成的规则,但是你可以覆盖这些规则。
  • 扩展性:Gradle允许通过扩展来自定义任务类型,甚至构建模型
  • IDE支持:各种主流IDE都支持Gradle,例如Intellij IEAD,Eclipse,Visual Studio
  • Insight:Build scans提供了有关构建运行的广泛信息,可用于识别构建问题。他们特别擅长帮助您确定构建性能方面的问题。您还可以与他人共享构建扫描,如果您需要寻求解决构建问题的建议,这将特别有用。

由于Gradle强大而又灵活,初次使用的可能会让你无从下手,通过了解下面5个核心原则,有助于更快上手Gradle:

  • Gradle是一款通用的构建工具:Gradle允许您构建任何软件,因为它对您要构建的内容或应如何完成的工作几乎不作任何假设。但是有一个明显的限制:依赖项管理当前仅支持与Maven和Ivy兼容的存储库以及文件系统。
  • 基于任务的核心模型:Gradle将其构建模型建模为任务的有向无环图。这意味着构建实质上配置了一组任务,并根据它们的依赖关系将它们连接在一起以创建该有向无环图。创建任务图后,Gradle将确定需要按顺序运行的任务,然后按顺序执行这些任务。

  • Gradle有几个固定的构建阶段:初始化阶段设置构建环境,并确定哪些项目将参与其中;配置阶段构造和配置构建的任务图,然后根据用户要运行的任务确定需要运行的任务和运行顺序;执行阶段运行在配置阶段结束时选择的任务。
  • Gradle有多种扩展方式:定制任务类型;定制任务的行为;扩展项目或任务的属性;自定义约定;自定义模型。
  • 构建脚本对API进行操作:Gradle的构建脚本就是可执行代码。但这只是实现细节:精心设计的构建脚本描述了构建软件所需的步骤,而不是这些步骤应该如何工作。这是定制任务类型和插件的工作。

二、为什么用Gradle?

1. 速度, gradle使用构建缓存、守护进程等方式提高编译速度。结果就是gradle的编译速度要远超maven,平均编译速度比Maven快好几倍,而且项目越大,这个差距就越明显。

2. 灵活性, gradle要比Maven灵活太多,虽然有时候灵活并不是一件好事情。但是大部分情况下,灵活一点可以极大的方便我们。Maven死板的XML文件方式做起事情来非常麻烦。很多Maven项目都通过执行外部脚本的方式来完成一些需要灵活性的工作。而在gradle中配置文件就是构建脚本,构建脚本就是编程语言(groovy编程语言),完全可以自给自足,无需外部脚本。

3. 简洁性, 完成同样的功能,gradle脚本的长度要远远短于maven配置文件的长度。虽然很多人都说XML维护起来不麻烦,但是我觉得,维护一个光是依赖就有几百行的XML文件,不见得就比gradle脚本简单。

三、Gradle的安装与Grovvy语言

3.1 Gradle的安装

下载地址:services.gradle.org/distributio…

目录结构:gradle-x.x-bin.zip 发行版

gradle-x.x-src.zip源码

gradle-x.x-all.zip 全部文件

第一步: 将下载的压缩包解压到本机的指定目录即可

第二步: 配置环境变量

(1)首先右键“此电脑”-->"属性"-->"高级系统设置"-->"环境变量"-->"系统变量"

(2)然后在用户变量或系统变量下新建一个变量为GRADLE_HOME的变量,并将Gradle的安装目录路径(D:\Program Files\gradle-7.4)设置为变量值

(3)修改path变量,将Gradle的bin添加到path变量值中: ;%GRADLE_HOME%\bin , 注意:前面的分号(;)变量中如果没有就不能少

第三步: 测试是否安装成功;打开cmd,并输入 gradle -v 查看Gradle版本信息

3.2 Grovvy语言简单使用

// grovvy编程语言
println("hello world")
println "hello world"

// 定义变量
// def弱类型
def i = 18
println i

def str = "张三今年24"
println str

// 定义集合类型
def list = ['a','b','c']
println list

// 添加元素
list << 'd'
list.add("e")
println list
println list.get(3)

// 定义一个map
def map = ['k1':'v1','k2':'v2']
// 向map中添加键值对
map.k3 =  'v3'
println map.get("k3")

// grovvy中的闭包
// 定义一个闭包
def b1 = {
    println "hello b1"
}
def method1(Closure closure){
        closure()
}
method1(b1)

// 定义一个带参闭包
def b2 = {
    v -> println "hello ${v}"
}
def method2(Closure closure){
    closure("小王")
}
method2(b2)

四、Gradle入门

4.1 Hello World

task hello{
    doLast{
        println "Hello Gradle"
    }
}
输出:
Hello Gradle

简洁方式:

注意:操作符 << 在Gradle 4.x中被弃用(deprecated),并且在Gradle 5.0 被移除(removed)

task hello{
     println "Hello Gradle"
}
输出:
Hello Gradle

4.2 Gradle Wrapper

4.2.1 Gradle Wrapper 简介

      1.1 Wrapper,顾名思义,就是 Gradle 的一层包装,便于在团队开发过程中统一 Gradle 构建的版本。这样大家都可以用统一的 Gradle 版本进行构建工程,可以避免因为 Gradle 版本不统一而带来的问题。

      1.2 一般在项目开发中,用的都是 wrapper 这种方式,而不是自己下载 gradle 的压缩包,解压后配置 gradle 环境变量的方式。 wrapper 在 Windows 下是一个批处理文件,在 Linux 下是一个 shell 脚本。当使用 wrapper 启动 gradle 的时候,wrapper 会自动检查 gradle 是否被下载关联,如果没有则会从配置的地址进行下载并运行构建。这种方式对开发人员是非常方便的,因为不用再去专门配置 gradle 环境了,只要执行 wrapper 命令即可,wrapper 它会自动搞定一切。在IDE 中就是这种方式。

4.2.2 生成 Wrapper

2.1 Gradle 提供了内置的任务 wrapper task 来自动生成 wrapper 所需的目录及文件,在项目的根目录中(一般是 build.gradle 的路径下)输入命令 gradle wrapper 即可生成.

2.2 各个文件的作用说明如下:

(1) gradlew 和 gradlew.bat 分别 Linux 和 Windows 下的可执行脚本。用法和 Gradle 原生命令是一样的。比如同样执行 taskHello 任务,两种命令的结果是相同的。

但是有一点需要注意: gradle taskHello 是用在系统环境变量中配置的 Gradle 版本来执行任务的,如果找不到 Gradle 则会报错
gradlew taskHello 是用在   ./gradle/wrapper/gradle-wrapper.properties 配置的 Gradle 版本来执行任务的,如果找不到对应的 Gradle 则会去配置的链接中下载,下载的默认路径是 C 盘中的 .gradle 文件夹。

(2) gradle-wrapper.jar 是具体业务逻辑实现的 jar 包 gradlew 最终还是使用 java 执行这个 jar 包来执行 Gradle 的相关操作。 (3) gradle-wrapper.properties 是配置文件,用于配置使用哪个版本的 Gradle。

2.3 生成的这些 wrapper 文件可以随着项目工程一起提交到版本控制系统里面(比如 git),这样后续开发也会按照提交的配置好的 Gradle 版本进行统一构建开发。

4.2.3 wrapper 配置

3.1 在执行命令 gradle wrapper 时可以指定一些参数来控制 wrapper 的生成。具体有如下两个配置参数:

--gradle-version  用于指定使用的 Gradle 的版本
--gradle-distribution-url 用于指定下载 Gradle 版本的URL,该值的规则是 http://services.gradle.org/distributions/gradle-${gradleVersion}-bin.zip

3.2 gradle-wrapper.properties 是 gradle 的配置文件。在执行命令 gradle wrapper 时的参数配置会写入该文件中,具体的字段说明如下

distributionBase    下载 Gradle 压缩包解压后存储的主目录
distributionPath    相对于 distributionBase 的解压后的 Gradle 压缩包的路径 
zipStoreBase         distributionBase,区别是存放的是 zip 压缩包
zipStorePath         distributionPath,区别是存放的是 zip 压缩包
distributionUrl     Gradle 发行版本压缩包的下载地址  ---- 比较关注的是这个配置字段

3.3 如果运行 ./gradlew 的时候一直卡着不动,可能是因为官方的 Gradle 地址被封闭了,可以把 distributionUrl 换成其他的镜像地址尝试。

4.2.4 自定义配置 wrapper task 生成 gradle wrapper

4.1 我们可以对 wrapper task 进行修改,生成自定义配置的 gradle-wrapper.properties

4.2 在 build.gradle 构建脚本中配置以下代码:

wrapper(){
     gradleVersion = '7.4'
     archiveBase = 'GRADLE_USER_HOME'
     archivePath = 'wrapper/dists'
     distributionBase = 'GRADLE_USER_HOME"'
     distributionPath = 'wrapper/dists'
     distributionUrl = 'http://services.gradle.org/distributions/gradle-7.4-all.zip'
}

这样在执行 gradle wrapper 就会生成7.1版本的 wrapper 了,而不用使用 --gradle-version 7.1 这样的命令进行指定了。

4.3 日志

4.3.1 日志级别

1.1 下表列出了 Gradle 的6中日志级别以及它们的作用:

ERROR        错误消息
QUIET        重要消息
WARNING      警告消息
LIFECYCLE    进度消息
INFO         信息消息
DEBUG        调试消息

1.2要使用这些日志级别,需要通过命令行选项中的日志开关来控制, 比如

 # 输出 QUIET 级别及其之上的日志信息
 gradle -q tasks  
 # 输出 INFO 级别及其之上的日志信息
 gradle -i tasks

1.3 通过命令行开关可以控制的日志选项

无选项            LIFECYCLE 及其更高级别
-q 或 --quiet     QUIET 及其更高级别
-i 或 --info      INFO 及其更高级别
-d 或 --debug     DEBUG 及其更高级别

4.3.2 输出堆栈信息

2.1 在使用 Gradle 构建的时候跟写代码一样,需要根据日志分析来解决问题。除了日志信息之外,Gradle 还提供了堆栈信息的打印

2.2 默认情况下,堆栈信息的输出是关闭的,需要我们通过命令行的堆栈信息开关打开,这样在构建工程失败的时候,Gradle 才会输出错误堆栈信息,便于我们分析定位问题。

2.3 错误堆栈开关选项

无选项                     没有堆栈信息输出
-s 或 --stacktrace         输出关键性的堆栈信息
-S 或 --full-stacktrace    输出全部的堆栈信息

2.4 一般推荐使用 -s 而不是 -S, 因为 -S 输出的堆栈太多太长,非常不好看;而 -s 比较精简,并且足够我们定位分析问题。

4.3.3 使用日志调试信息

3.1 在编写 Gradle 脚本时,有时需要一些日志打印来验证。可以使用 Gradle 提供的日志功能。

3.2 通常情况下都是使用 print 方法,它被 Gradle 定向为 QUIET 级别的日志

3.3 除了 print 方法外,也可以使用内置的 logger 更灵活地控制输出不同级别的日志信息:

logger.quiet('quiet 日志信息')
logger.error('error 日志信息')
logger.warn('warn 日志信息')
logger.lifecycle('lifecycle 日志信息')
logger.info('info 日志信息')
logger.debug('debug 日志信息')

3.4 例如:如果要打印出上面所有级别的信息,需要使用 debug 级别的日志开关,比如:gradle -d hello

4.4 命令行

4.4.1 帮助功能

Gradle 命令行里面也有帮助命令:

# 第一种方式:
gradle -h 或 gradle --help 或 gradle -?
# 第二种方式:
./gradlew -? 或 ./gradlew -h 或 ./gradlew -help

4.4.2 查看所有可执行的 Task

如果需要查看哪些 task 可执行,都具备什么功能。可以通过./gradlew tasks命令查看。

4.4.3 强制刷新依赖

3.1 在项目中有时候一个功能会依赖很多第三方库。像 Maven 这类工具都是有缓存的,因为不可能每次编译的时候都去下载第三方库。所以会在第一次使用第三方库的时候把它下载缓存,下次使用时会优先使用缓存。

3.2 使用缓存时也有例外,比如下载和缓存的版本不一样时,或者 debug 版本和 release 版本时,就可以通过强制刷新解决。

3.3 强制刷新很简单,只要在命令行运行的时候加上 --refresh-dependencies参数就可以了。例如:

./gradlew --refresh-dependencies assemble

4.4.5 多任务调用

有时候在项目中需要运行多个任务,比如在执行 jar 命令之前先执行 clean。通过命令行执行多个任务非常简单,只要按照任务顺序用空格分开即可。例如:

./gradlew clean jar

4.4.6 使用任务名字的缩写执行任务

有时候任务的名字很长,如果在执行的时候全部写出来也很费时间的。因此 Gradle 提供了驼峰命名法的缩写调用方式。比如:connectCheck,在执行的时候可以有下面两种写法:

# 第一种写法
./gradlew connectCheck
# 第二种写法
./gradlew cc

五、Gradle基础

5.1 项目结构

├── gradle //为包装文件生成的文件夹
│   └── wrapper
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradlew //Gradle 包装器启动脚本
├── gradlew.bat //Gradle 包装器启动脚本
├── settings.gradle //用于定义构建名称和子项目的设置文件
└── app
    ├── build.gradle //app项目的构建脚本
    └── src
        ├── main
        │   └── java //默认 Java 源文件夹
        │       └── demo
        │           └── App.java
        └── test
            └── java //默认 Java 测试源文件夹
                └── demo
                    └── AppTest.java

5.2 熟悉build.gradle

5.2.1构建脚本常用属性

group

项目所属组。配置的是项目所属组名称。

group 'com.zhf.demo'
sourceCompatibility

用于编译源文件的java版本,默认为当前JVM版本。

//配置java版本为1.8
sourceCompatibility = 1.8
repositories

repositories中可以配置各种仓库。寻找依赖的过程是依照你配置仓库项的顺序执行的。一般会将本地仓库配置在前,其次是私服,而后是中央仓库,这也是为了能最快的找到需要的依赖包。

repositories {
    mavenLocal()
    maven { url 'http://192.168.1.1:80/content/groups/public' }
    maven { url 'http://192.168.1.1:80/content/groups/public-snapshots' }
    mavenCentral()
}
dependencies

项目依赖项处理程序。用来配置引入的依赖项。

关键字说明
compile具有依赖传递
implementation仅实现依赖(不具有传递性,即使用该关键字的包对于其它module是不可见的)
compileOnly仅编译时依赖,运行时不使用
annotationProcessor编译期间使用的注释处理器
runtimeOnly仅运行时依赖项
testImplementation仅实现测试的依赖项
testCompileOnly附加依赖项仅用于编译测试,不在运行时使用
testRuntimeOnly运行时仅依赖于运行测试
archives该项目生产的工件(例如罐子)Gradle 使用它来确定构建时要执行的“默认”任务
dependencies {
    //单个依赖
    implementation group: 'com.alibaba', name: 'fastjson', version: '1.2.73'
    //单个依赖简写
    implementation 'com.alibaba:fastjson:1.2.73'
    //多个依赖
    implementation 'com.alibaba:fastjson:1.2.73', 'log4j:log4j:1.2.17'
    //闭包依赖,为了添加额外配置
    implementation("org.mybatis:mybatis:3.5.6"){
        exclude group :"org.springframework",module:"spring"
        exclude group :"org.javassist",module:"javassist"
        exclude group :"org.jboss.netty",module:"netty"
    }
    //双引号方式使用变量,在ext中声明或 def 关键字声明变量 lombok_version=具体版本
    annotationProcessor "org.projectlombok:lombok:$lombok_version"
    compileOnly "org.projectlombok:lombok:${lombok_version}"
}
configurations

项目配置。可以配置全局排除依赖。

configurations {
    all{
        exclude group :"org.springframework.boot",module:"spring-boot-starter-logging"
    }
    //编译期排除
    //compile.exclude module: 'spring-boot-starter-logging'
    //在构建过程中排除
    //all*.exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
//简写
configurations.all*.exclude module: "spring-boot-starter-logging"
buildscript

buildscript中声明的是gradle脚本自身需要使用的资源。可以声明包括变量、任务、依赖项、第三方插件、maven仓库地址等。gradle在执行脚本时会优先执行该代码块中的内容,而后执行其它脚本。

buildscript {
  //变量
  ext {
    spring_boot_version = '2.3.4.RELEASE'
    spring_dependency_management_version = '1.0.10.RELEASE'
  }
  
  //maven仓库
  repositories {
    mavenLocal()
    maven { url 'http://192.168.1.1:80/content/groups/public' }
    maven { url 'http://192.168.1.1:80/content/groups/public-snapshots' }
    mavenCentral()
  }
  
  //依赖项
  dependencies {
    classpath "io.spring.gradle:dependency-management-plugin:${spring_dependency_management_version}"
    classpath "org.springframework.boot:spring-boot-gradle-plugin:${spring_boot_version}"
  }
  
  //任务
  task myTask(){
  	//处理任务
  }
}
plugins

plugins中配置的是gradle脚本使用到的插件。如果使用的是核心插件如 ‘java’无需指定版本,使用的是“社区插件”则必须指定version。

plugins 与 apply plugin 效果是一样。apply plugin是使用较早,plugins是高版本后添加的特性,区别在于 plugins 中指定的插件必须是插件中心 plugins.gradle.org/存在的,此外apply plugin 可以用在 allprojects 和 subprojects 中。

1.高版本引入插件方式(gradle 2.1及以上):plugins

plugins {
    id 'java'
    id 'application'
    id 'org.springframework.boot' version '2.3.4.RELEASE'
}

2.遗留版本引入插件(结合buildscript):apply plugin

buildscript {
    ext {
        spring_boot_version = '2.3.4.RELEASE'
    }
    
    repositories {
        mavenLocal()
    	maven { url 'http://192.168.1.1:80/content/groups/public' }
    	maven { url 'http://192.168.1.1:80/content/groups/public-snapshots' }
    	mavenCentral()
    }
	//先引入插件
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_version")
    }
}
apply plugin: 'java'//核心插件不需要在buildscript中提前引入,且不需要指定版本
apply plugin: 'application'//核心插件不需要在buildscript中提前引入,且不需要指定版本
apply plugin: 'org.springframework.boot'//中心插件,需要与buildscript结合提前引入,引入之后在这里使用无需加版本号

5.3 Gradle的生命周期

大致流程如下:

1)Initialization初始化阶段

2)Configuration配置阶段

3)Execution执行阶段

Initialization初始化阶段,解析整个工程中所有Project,构建所有Project的对应的project对象

Configuration配置阶段,解析所有projects对象中的task,构建好所有task的拓扑图

Execution执行阶段,执行具体的task及其依赖的task,顺序是先把依赖的执行完,才去执行自己

初始化阶段开始

只需在setting.gradle 文件中写逻辑即可。每次构建都会先加载setting.gradle文件。

// 初始化阶段
gradle.settingsEvaluated {
    println 'settingsEvaluated'
}
// 加载
gradle.projectsLoaded  {
    println 'projectsLoaded'
}

// 配置阶段
gradle.beforeProject {
    println 'beforeProject'
}

声明周期的常见监听方法

bulid.gradle

// 钩子方法
gradle.afterProject {
    println 'afterProject'
}
project.beforeEvaluate {
    println 'beforeEvaluate'
}
gradle.projectsEvaluated {
    println 'projectsEvaluated'
}
project.afterEvaluate {
    println 'afterEvaluate'
}
gradle.taskGraph.whenReady {
    println 'whenReady'
}

// 执行阶段
gradle.taskGraph.beforeTask {
    println "before task"
}
gradle.taskGraph.afterTask {
    println "afterTask "
}
gradle.buildFinished {
    println 'buildFinished'
}

task t1{
    println "i am task1"
}

六、Gradle的使用

6.1 依赖版本管理

在gradle官方文档中明确指出,如果想使用依赖关系管理,那就需要使用的gradle版本大于4.4

6.1.1 使用插件

方式1:使用插件并指定版本

plugins {
    id 'java'
    //指定版本
    id 'org.springframework.boot' version "2.3.4.RELEASE"
    //配置依赖管理插件,自定义托管版本
    id 'io.spring.dependency-management' version "1.0.10.RELEASE"
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    testImplementation "org.springframework.boot:spring-boot-starter-test"
}

方式2:使用插件,自动追加版本

plugins {
    id 'java'
    //指定版本
    id 'org.springframework.boot' version "2.3.4.RELEASE"
}

//应用依赖管理插件,自动给插件追加版本号
apply plugin: "io.spring.dependency-management"

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    testImplementation "org.springframework.boot:spring-boot-starter-test"
}
使用io.spring.dependency-managemen插件

io.spring.dependency-managemen是SpringBoot一个用于依赖管理的插件,引入这个插件后,会下载一个类似pom.xml文件。里面对应了 一些常见的jar包版本,这样就可以不用自己自动版本了。其他依赖使用的版本都是根据plugins里的org.springframework.boot版本来自动匹配的。使用maven bom的方式也可实现依赖版本的管理。

注意:因为对于spring cloud来说,spring boot插件并不像自动引入spring-boot-dependencies那样自动引入spring cloud的bom,因此需要我们自己显式地引入spring cloud相关的bom。

6.1.2 Maven BOM管理

使用 BOM 方式管理 spring-cloud依赖版本

plugins {
    id 'java'
    id 'org.springframework.boot' version "2.3.4.RELEASE"
    id 'io.spring.dependency-management' version "1.0.10.RELEASE"
}

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-web'
	implementation "org.springframework.cloud:spring-cloud-starter-config"
	implementation "org.springframework.cloud:spring-cloud-starter-openfeign"
}

dependencyManagement {
    imports {
    	mavenBom "org.springframework.cloud:spring-cloud-dependencies:${spring_cloud_version}"
    }
}

6.1.3 其他依赖

文件依赖:

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation files('libs/xxx.jar')
    implementation files('libs/xxxApi.jar')
}

项目依赖:

1.项目是一个根项目,依赖项位于其根目录下
当依赖的项目位于目录结构的根目录下时(除了此项目之外,没有与其他项目共享依赖项),可以使用推荐的gradle策略来完成)

目录结构:

Project
  |--build.gradle
  |--settings.gradle
  |--project1
  |    |--build.gradle

然后要将project1添加到Project,Project / settings.gradle内容,如下所示:

include ':project1'

在Project / build.gradle依赖项部分中,需要通过添加以下内容来编译依赖项:

dependencies {
   compile project(':project1')
}

2.两个独立的项目,需要使用其中一个作为依赖项
当两个项目在目录结构中处于同一级别时,并没有按照gradle团队的意愿进行操作,但是我认为这是更现实的情况,这是因为您拥有可以在其他几个项目中轻松使用的库项目项目作为依赖项。

目录结构:

Project
  |--build.gradle
  |--settings.gradle
Project1
  |--build.gradle

要将依赖项添加到项目中,需要include它,并手动显示依赖项路径。因此,Project / settings.gradle内容应如下所示:

include ':Project1'
project(':Project1').projectDir = new File(settingsDir, '../Project1')
12

在Project / build.gradle依赖项部分中,需要通过添加以下内容来编译依赖项:

dependencies {
	compile project(’:Project1’)
}

6.2 项目编译

6.2.1.编译乱码处理

//在 build.gradle 增加以下配置
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
}

6.2.2 跳过测试编译

//在 build.gradle 增加以下配置
gradle.taskGraph.whenReady {
    tasks.each { task ->
        if (task.name.contains("test")) {
            task.enabled = false
        }
    }
}
或者执行
gradle build -x test

6.3 发布本地

1.build.gradle配置

// 1.配置分组,版本号
group 'com.zhf.demo'
version '0.0.1-SNAPSHOT'
// 3.配置maven插件
plugins {
    id 'maven-publish'
}

//发布本地,包名为文件 settings.gradle 中 rootProject.name 配置的名称,版本为上文配置的 verison 版本号 默认存储路径可以
publishing {
    publications {
        maven(MavenPublication) {
            from(components.java)
        }
    }
}

\

2.使用idea右边插件列表执行发布

6.4 依赖冲突解决

在项目中,经常会遇到依赖冲突,主要可以通过报错中分析具体冲突的依赖包,或通过上一步中查看依赖关系来分析存在的依赖包冲突从而进行包的版本统一,或者排除冲突包来解决问题。

1.通过配置全局排除冲突包(全局封杀),如:

//方式一
configurations {
    all{
        exclude group :"org.springframework.boot",module:"spring-boot-starter-logging"
    }
}

//方式二 简写
configurations.all*.exclude module: "spring-boot-starter-logging"

2.诊断出具体依赖项冲突可以排除具体包,如:

dependencies {
    implementation("org.mybatis:mybatis:3.5.6"){
        exclude group :"org.springframework",module:"spring"
        exclude group :"org.jboss.netty",module:"netty"
    }
}

3.强制指定版本策略,即在发生冲突时使用指定的版本,如:

//冲突失败策略设置
configurations.all {
    resolutionStrategy {  failOnVersionConflict() }
}
//强制指定版本策略设置
dependencies {
	//方式一 闭包
    implementation ("io.netty:netty-all:4.0.44.Final"){
        force true
    }
    //方式二 简写
    implementation group: 'io.netty', name: 'netty-all', version: '4.0.44.Final', force: true
}

4.在平时使用动态依赖来减小发生版本冲突的几率,如:

dependencies {
    //方式一:指定某个版本以上,减小发生版本冲突的几率。如以下依赖选择 3 以上任意一个版本
    implementation 'cn.afterturn:easypoi-base:3.+'
    // 方式二:选择最新的版本
    implementation 'cn.afterturn:easypoi-base:latest.integration'
}

6.5 打成war包

1.修改gradle.build文件 添加 war

plugins {
    id 'war'
}
或
apply plugin: 'war'

2.主类继承SpringBootServletInitializer,重写configure方法

@SpringBootApplication
public class StuApplication extends SpringBootServletInitializer {
    public static void main(String[] args) {
        SpringApplication.run(StuApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(StuApplication.class);
    }
}

如需排除springboot内置tomcat,排除即可。

6.6 自定义插件

6.6.1 build.gradle中

1.
task t1{
    println "my test t1"
}
2.
task hello(type: GreetingTask)

class GreetingTask extends DefaultTask {
    @TaskAction
    def greet() {
        println 'hello from GreetingTask'
    }
}

6.6.2 创建一个groovy工程

1.新建一个名为buildsrc的groovy项目和src目录同级

2.创建如下图所示目录结构

在build.gradle中添加如下配置(比较固定)

apply plugin: 'groovy'

dependencies {
    compile gradleApi()
    compile localGroovy()
}

3.创建Groovy脚本

在脚本中通过实现gradle的Plugin接口,实现apply方法就可以

package com.plugin

import org.gradle.api.Plugin
import org.gradle.api.Project

public class HelloPlugin implements Plugin<Project> {
    @Override
    void apply(Project project) {
        project.task('testPlugin')  {
            println 'hello gradle plugin'
        }
    }
}

resources文件夹是标识整个插件的文件夹。其文件夹下的结构例如以下所看到的:

└── resources
└── META-INF\
└── gradle-plugins

该文件夹结构与buildSrc一样,是Gradle插件的默认文件夹,不能有不论什么改动。创建好这些文件夹后,在gradle-plugins文件夹下创建——插件名.properties文件。内容如下,为包的全限定类名。

implementation-class=com.plugin.HelloPlugin

4.在主项目中使用插件

在主项目的build.gradle文件里,通过apply指令来载入自己定义的插件。脚本例如以下所看到的:

apply plugin: 'pluginsrc' // 或 用id 'pluginsrc'

当中plugin的名字。就是前面创建pluginsrc.properties中的名字--pluginsrc。

配置完毕后,即可使用,如下图所示。

也可使用命令到目录下gradle testPlugin执行。

6.6.3 独立插件项目发布到本地引用

1.新建一个gradle工程 选择groovy语言。

2.除build.gradle中需要添加发布插件,其余编写插件步骤与在项目中编写插件过程一致。

plugins {
    id 'groovy'
    id 'maven-publish'
}

group 'com.zhf'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    compile gradleApi()
    compile localGroovy()
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId 'com.plugins'
            artifactId 'firstplugin'
            version '1.0.0'
            from components.java
        }
    }
}

publishing {
    repositories {
        maven {
            // change to point to your repo, e.g. http://my.org/repo
            url uri('D:/repos')
        }
    }
}

3.添加发布插件

plugins {
    id 'groovy'
    id 'maven-publish'
}

group 'com.zhf'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

dependencies {
    compile gradleApi()
    compile localGroovy()
}

publishing {
    publications {
        mavenJava(MavenPublication) {
            groupId 'com.plugins'
            artifactId 'firstplugin'
            version '1.0.0'
            from components.java
        }
    }
}

publishing {
    repositories {
        maven {
            // 发布到本地了指定路径 
            url uri('D:/repos')
        }
    }
}

切换到目录下gradle pulish

4.在其他项目中引用,在build.gradle中添加如下配置。运行即可

buildscript {
   repositories {
      maven {
         //local maven repo path
         url uri('D:/repos')
      }
   }
   dependencies {
      classpath 'com.plugins:firstplugin:1.0.0'
   }
}
apply plugin: 'firstPlugin'

7、Maven转Gradle

1.Maven项目转Gradle项目,在pom文件所在的目录中 打开Terminal中输入以下命令进行构建。

gradle init --type pom

2.重新导入项目以Gradle形式