1、安装gradle
代码语言:javascript复制brew install gradle
2、Hello World
1、创建构建脚本文件:build.gradle
2、编写构建脚本:
代码语言:javascript复制task hello{
doLast{
println 'hello world'
}
}
task:构建脚本定义一个任务,并取名。doLast:构建脚本给任务添加一个动作Action,在task执行完毕后,要回调doLast这部分闭包的业务代码逻辑或者叫回调实现。
3、执行构建脚本:
代码语言:javascript复制gradle -q hello
执行gradle命令,会默认加载当前目录下的build.gradle脚本文件,也可以通过-b参数指定加载执行的文件。
-q 控制gradle输出的日志级别。
Groovy将println()添加java.lang.Object,方法调用可以省略括号,以空格分开,单引号双引号包含内容都是字符串。
4、输出:
代码语言:javascript复制hello world
3、Gradle Wrapper
gradle wrapper
gradle wrapper 是对Gradle的一层包装,便于在开发过程中统一Gradle构建的版本。
代码语言:javascript复制gradle wrapper
自动生成Wrapper所需要的目录文件。
gradlew和gradlew.bat是Linux和Windows下的可执行脚本。
指令参数:
代码语言:javascript复制--gradle-version 指定使用的gradle版本
代码语言:javascript复制--gradle-distribution-url 指定下载gradle发行版的url地址
gradle-wrapper.properties
配置字段:
代码语言:javascript复制distributionBase 下载的Gradle压缩包解压后存储的主目录
distributionPath 相对于distributionBase的解压后的Gradle压缩包的路径
zipStoreBase 同distributionBase,只不过是存放zip压缩包的
zipStorePath 同distributionPath,只不过是存放zip压缩包的
distributionUrl Gradle发行版压缩包的下载地址
wrapper task
自定义wrapper task:
代码语言:javascript复制task wrapper(type: Wrapper){
gradleVersion = '6.5.1'
archiveBase = 'GRADLE_USER_HOME'
archivePath = 'wrapper/dists'
distributionBase = 'GRADLE_USER_HOME'
distributionPath = 'wrapper/dists'
distributionUrl = 'http://services.gradle.org/distributions/gradle-6.5.1-all.zip'
}
4、Gradle日志
日志级别:
代码语言:javascript复制ERROR 错误信息
QUIET 重要信息
WARNING 警告信息
LIFECYCLE 进度信息
INFO 内容信息
DEBUG 调试信息
设置日志开关选项:
代码语言:javascript复制# 输出QUIET级别及其之上的日志信息
gradle -q tasks
代码语言:javascript复制无选项 LIFECYCLE及更高级别
-q 或 --quiet QUIRT及更高级别
-i 或 --info INFO及更高级别
-d 或 --debug DEBUG及更高级别(全部日志)
设置错误堆栈开关选项:
代码语言:javascript复制无选项 不输出堆栈信息
-s 或 --stacktrace 输出关键性的堆栈信息
-S 或 --full-stacktrace 输出全部堆栈信息
使用日志信息调试:其实是调用Project的getLogger获取Logger对象的实例。
代码语言:javascript复制logger.quiet('quiet 日志')
logger.error('error 日志')
logger.warn('warn 日志')
logger.lifecycle('lifecycle 日志')
logger.info('info 日志')
logger.debug('debug 日志')
5、Gradle命令行
帮助:
代码语言:javascript复制./gradlew -?
./gradlew -h
./gradlew -help
查看所有可执行Tasks:
代码语言:javascript复制./gradlew tasks
Gradle Help任务:Gradle内置了一个help task,了解每一个Task的使用帮助。
代码语言:javascript复制./gradlew help --task tasks
强制刷新依赖:
代码语言:javascript复制./gradlew --refresh-dependencies assemble
多任务调用:执行jar之前先clean,只需按顺序空格分开。
代码语言:javascript复制./gradlew clean jar
通过任务名缩写执行:Gradle 提供了基于驼峰命名的缩写调用,如doCheck任务。
代码语言:javascript复制./gradlew dc
6、Groovy
Groovy是基于JVM的一种动态脚本语言,支持闭包,支持DSL。
字符串
Groovy中,分号不是必须的。单引号和双引号都表示字符串,但是只有双引号里才能做表达式运算。表达式:
代码语言:javascript复制${表达式}
代码语言:javascript复制$单个变量
集合
Groovy兼容了Java集合,并进行扩展。
List:
代码语言:javascript复制 class ListTest {
public static void main(String[] args) {
//创建ArrayList
def list = [1, 2, 3, 4, 5]
//[1, 2, 3, 4, 5]
println list
//java.util.ArrayList
println list.getClass().getName()
//1
println list[0]
//最后一个元素 5
println list[list.size() - 1]
//最后一个元素 5
println list[-1]
//倒数第二个元素 4
println list[-2]
//使用Range对象获取集合中的几个连续值[3, 4, 5]
println list[2..4]
def subList = list[2..4]
//<java.util.ArrayList@1c3e4a2 elementData=[1, 2, 3, 4, 5] size=5 modCount=1>
println list.dump()
//<java.util.ArrayList@8023 elementData=[3, 4, 5] size=3 modCount=1>
println subList.dump()
//[1, 2, 3, 4, 5]
println list[0..list.size() - 1]
//[2, 3, 4, 5]
println list[1 - list.size()..-1]
//true
println ![]
//true
println([1] && ['a'] && [0] && [0.0] && [false] && [null])
//正向迭代 12345
list.each { print it }
//反向迭代 54321
list.reverseEach { print it }
println()
//如果关注迭代的索引和计数
list.eachWithIndex { int entry, int i -> println "value:" entry.intValue() "==index:" i }
//闭包中的元素求和 15
def sum = 0
list.each { sum = it }
println sum
//[2, 4, 6, 8, 10]
def result = []
//<< 操作符映射到leftShitf()方法
list.each { result << it * 2 }
println result
//在集合中的每个元素上执行操作并返回一个结果集合使用collect
//[3, 6, 9, 12, 15]
println list.collect { it * 3 }
//find会对集合进行迭代,当闭包返回true则终止迭代(匹配第一个),会将当前元素返回
//如果遍历结束也找到,则返回null.以下输出:4
println list.find { it == 4 }
//以下输出索引3
println list.findIndexOf { it == 4 }
//findAll 查找所有返回的是对象[3, 4, 5]
println list.findAll { it > 2 }
}
}
代码语言:javascript复制 def static listIterator() {
def list = [1, 2, 3, 4, 5]
//正向迭代 12345
list.each { print it }
//反向迭代 54321
list.reverseEach { print it }
println()
//如果关注迭代的索引和计数
list.eachWithIndex { int entry, int i ->
println "value:" entry.intValue() "==index:" i
}
//闭包中的元素求和 15
def sum = 0
list.each { sum = it }
println sum
//[2, 4, 6, 8, 10]
def result = []
//<< 操作符映射到leftShitf()方法
list.each { result << it * 2 }
println result
//在集合中的每个元素上执行操作并返回一个结果集合使用collect
//[3, 6, 9, 12, 15]
println list.collect { it * 3 }
//find会对集合进行迭代,当闭包返回true则终止迭代(匹配第一个),会将当前元素返回
//如果遍历结束也没找到,则返回null.以下输出:4
println list.find { it == 4 }
//以下输出索引3
println list.findIndexOf { it == 4 }
//findAll 查找所有返回的是对象[3, 4, 5]
println list.findAll { it > 2 }
//30
println list.collect({ it * 2 }).sum()
//inject对集合中的每个元素都调用闭包,0为初始值 。输出:15
println list.inject(0) { total, ele -> total ele }
//连接集合中的每个元素,输出:1,2,3,4,5
println list.join(",")
}
Map:
代码语言:javascript复制 def static mapBasic(){
//定义空map
def emptyMap = [:]
println emptyMap
//定义多个key的map ,默认情况下 没有引号,''或者""的key都是字符串类型
def map = [aa: "jannal", '2': "lisi", "3": "wangwu"]
//java.util.LinkedHashMap
println map.getClass().name
//添加key
map << ['4': "jannal2"]
map.put('5', "jannal3");
//移除key
map = map - ['4': "jannal2"]
map -= ['4': "jannal2"]
map.remove("5")
//访问键的值 输出:jannal
println map["aa"]
//可通过.来访问,如果key特殊,可通过""
println map."aa"
println map.aa
//如果key不存在,返回一个默认值
println map.get("4","44444")
}
def static mapCollect(){
// 通过list创建map
def wordList = ['Apple', 'Banana', 'Cat']
//[Apple:5, Banana:6, Cat:3]
def wordCountMap = wordList.collectEntries{ [(it):it.length()] }
println(wordCountMap)
def longWords = wordCountMap.count { key, value->
value >= 4
}
//2
println "${longWords}"
//合并map
def map1 = [p1:100, p2:200]
def map2 = [p3:300, p4:400]
def map3 = map1 map2
//[p1:100, p2:200, p3:300, p4:400]
println "${map3}"
//取交集
def map4 = [p1:100, p2:200, p3:300, p4:400, p5:500]
def map5 = [p4:400, p5:500, p6:600, p7:700]
def map6 = map4.intersect(map5)
//[p4:400, p5:500]
println "${map6}"
}
def static iterator(){
def map = [aa: "jannal", '2': "lisi", "3": "wangwu"]
//如果只要一个参数,就得到entry,两个参数得到key和value
//迭代 输出: aa : jannal ;2 : lisi ;3 : wangwu ;
map.each { entry ->
print "$entry.key : $entry.value ;"
}
println()
//迭代 输出: aa : jannal ;2 : lisi ;3 : wangwu ;[aa1, 21, 31]
map.each { key, value ->
print "$key : $value ;"
}
println()
//[aa1, 21, 31]
println map.collect { key, value ->
key "1"
}
//找到即返回该map的key和value aa=jannal
println map.find { key, value ->
key == "aa"
}
//找到所有匹配的 [2:lisi, 3:wangwu]
println map.findAll { key, value ->
key == '2' || key == '3'
}
//不想得到元素,只是确定map中是否有任何元素满足条件用any
// 输出:true
//any会查找至少一个满足给定条件
println map.any { key, value ->
key == "2"
}
//是否所有的元素都满足条件 输出:false
println map.every { key, value ->
key == '2' || key == '3'
}
}
方法
括号可以省略。return可以不写,Groovy会把方法执行过程中的最后一句代码执行结果作为其返回值。代码块可以作为参数传递。
Java Bean
组件化、插件化、配置集成等都是基于JavaBean。
闭包 Closure
闭包是DSL的基础,使得代码灵活、轻便、可复用,不想Java一样需要类。
闭包就是代码块,当闭包有一个参数时,默认就是it,当有多个参数时,需要把参数一一列出。
闭包委托 Delegate
Groovy闭包支持闭包方法的委托。闭包有thisObject、owner、delegate三个属性。
代码语言:javascript复制this:
该属性指向定义闭包的类的实例对象。
owner:
该属性和 this 类似,但是闭包中也可以定义闭包的,如果闭包 A 内定义了闭包 B,那么闭包 B 的 owner 指向的是其外部的闭包 A。
delegate:
该值初始化时是和 owner 相同的,但是该值可以通过接口将其它对象赋值给 delegate,来实现方法的委托功能。
代码语言:javascript复制class Test {
def x = 300
def y = 400
def run() {
def data = [x: 10, y: 20]
def cl = { y = x y }
cl.delegate = data
cl.resolveStrategy = Closure.DELEGATE_FIRST
cl()
println x //这里不是在闭包中,访问的 x 当然还是成员变量了
println y
println data // 主要是 data,在闭包中期访问的 x 和 y 均是 data 中,所以其 y 变成了 10 20;
}
}
new Test().run()
代码语言:javascript复制300
400
[x:10, y:30]
DSL
Domain Specific Language 领域特定语言。Gradle就是一门基于Groovy专门解决自动化构建的DSL。