电子说
大家回想一下自己第一次接触Gradle
是什么时候?
相信大家也都是和我一样,在我们打开第一个AS项目的时候,
发现有很多带gradle字样的文件:setting.gradle, build.gradle,gradle.warpper
,以及在gradle
文件中各种配置,
这些都是啥wy啊。。
特别对于一些小公司开发人员,因为接触架构层面的机会很少,可能在使用AS几年后都不一定对Gradle
有太多深入了解,这是实话,因为笔者就是这么过来的。。
而Gradle
又是进阶高级
开发的必经之路。
好了,接下来进入正题,此系列笔者会由浅入深的方式,带领大家来了解下,Gradle
背后究竟有哪些奥秘。
很多开发喜欢把Gradle
简单定义为一种构建工具,和ant,maven
等作用类似,
诚然Gradle确实是用来做构建,但是如果简单得把Gradle拿来做构建,就太小看Gradle了.
笔者更愿意将Gradle看做一种编程框架
。在这个框架中,你可以做很多ant,maven等常用构建工具做不了的事情,
如将自己的任务task集成到构建生命周期中,完成文件拷贝,脚本编写等操作。
Gradle
优缺点:相较早期的构建工具:ant,maven等。
1.使用DSL Grovvy语言来编写: :了解ant的同学应该都知道:ant使用的是xml配置的模式,而Gradle使用的是表达性的Groovy
来编写,
Groovy同时支持面向对象和面向过程
进行开发,这个特性让Groovy
可以写出一些脚本的任务,这在传统ant,maven上是不可能实现的
2.基于java虚拟机: :Groovy
是基于jvm
的语言,groovy
文件编译后其实就是class文件,和我们的java
一样。
所以在gradle构建过程中,我们完全可以使用java/kotlin去编写我们的构建任务以及脚本,极大的降低我们学习的成本。
生命周期
中去,这在ant,maven上也是不可能实现的,用过gradle都知道,低版本gradle的项目在高版本的gradle中经常出现很多莫名其妙的错误,
向后兼容性较差
。
介绍了那么多,下面正式来讲解今天的主角:Groovy
Groovy
语法详解因为我们的Groovy和java很类似,所以这里我们以和java的差异性进行展开,这样可以更好的去理解groovy语法
java
:面向对象
groovy
:面向对象和过程
groovy不仅可以和java一样面向对象进程编程,也可以创建面向过程的脚本开发:
package variable
int i1 = 1
double d1 = 1
println(i1.class)
println(d1.class)
2.1:分号
:groovy默认行尾不加分号
2.2:public
:默认属性为public,而我们的java是protected
2.3:setter/getter
:groovy默认给我们类内部属性,创建setter和getter方法,外部只需要使用属性名访问即可
2.4:字符串
:groovy支持三种类型的字符串表达式定义
单引号
:不能使用+号代替,如果你确定这个字符串只是使用,不会更改那么你可以这么定义
//单引号定义不可更改内容
def s1 = 's1'
//使用转移字符://s'a'2
def s2 = 's\\'a\\'2'
双引号
:
在字符串内部可以使用{2+3}"
三引号:支持自动换行
一般我们会使用前两种,最后一种很少用
2.5:使用弱声明:def
,编译过程会自动类型检测,这个属性和kotlin的val/var
很像。
java
def str = "this is groovy str"
groovy中:使用def声明方法的返回值,如果没有返回值,则默认返回一个null
def echo(){
return "echo this"
}
groovy传入的参数可以省略参数类型,且可以设置参数默认值,有默认值调用的时候可以省略带默认值的参数
def echo(message,name = '123'){
return "echo:"+message +name
}
调用:echo("hello groovy")
使用return返回,如果省略return,则返回的是最后方法最后一行
def echo(){
"echo this"
}
println echo()
结果:"echo this"
groovy方法调用不像我们java,其内部给我们创建了很多判断的分支,支持在运行期动态添加方法
下面是groovy方法调用流程图:
gradle方法.png
invokeMethod
:对于类中所有调用方法:包括已定义和未定义方法,都会走到这个invokeMethod方法中,需要实现:GroovyInterceptable
接口
这个方法可以在我们方法执行器做一些方法类型参数等判断
class Person implements GroovyInterceptable{
def name
def age
def score
@Override
Object invokeMethod(String methodName, Object args) {
return "this method name is $methodName"
}
def helloGroovy(){
return "hello $name"
}
}
调用:
def per = new Person(name: 'lily')
println per.helloGroovy()
println per.helloGroovy1()
结果:
this method name is helloGroovy
this method name is helloGroovy1
可以看到所有的方法都被分派到invokeMethod且没有执行后续流程:这个和我们java运行期动态代理模式
有点类似,我们可以在invokeMethod
中实现一些AOP
的架构,如打印所有方法的统一日志
等。
methodMissing
:对于未定义的方法,如果重写这个methodMissing,则会调用这个方法
Object methodMissing(String name, Object args) {
println "methodMissing : $name"
}
最新版本groovy未发现这个方法,应该是被去掉了 。不过这个对于我们开发关系不大
元编程metaClass
:可以在运行期注入属性和方法包括静态方法,这个特性就比较厉害了,对于一些第三方类库,可以使用这个方式在运行期动态创建方法,相当于对类库进行了一次扩展学习过kotlin的都知道:扩展函数和扩展属性,差不多是这个用法
注入属性:
class Person implements{
def name
def age
}
//注入属性
Person.metaClass.sex = 'male'
def person1 = new Person(name: 'yuhb',age: 29)
println person1.sex
结果:male
注入方法:
//注入方法,使用闭包
Person.metaClass.sexUpperCase = { ->
sex.toUpperCase()
}
println person1.sexUpperCase()
结果:MALE
groovy中集合有三种:
列表List
:对应java中的Listdef list = [1, 2, 3, 4,5,6]
映射Map
:对应java中的Mapdef map = [key1:'value',key2:'value2']
注意:map中的key默认都是String类型的字符串,即使我们自己没加,编译器也会给我们加上
范围Range
:groovy中独有
def range = [1..100]
range其实就是指定了一个list的范围,而不需要一个一个列出来
如下使用:
/******switch case*****/
println getGrade(87)
def getGrade(def number){
def result
switch (number){
case 0..<60:
result = "不及格"
break
case 60..<80:
result = "及格"
break
case 80..100:
result = "优"
break
default:
result = "不确定"
break
}
result
}
所有集合都可以使用each
和eachWithIndex
进行遍历,当然也可以使用java中的for循环,但在groovy中一般不这么用
class Stu{
def name
def age
@Override
String toString() {
return "name:$name age:$age"
}
}
def students = [
1:new Stu(name: 'lily',age: 12),
2:new Stu(name: 'lucy',age: 13),
3:new Stu(name: 'tom',age: 14),
4:new Stu(name: 'sara',age: 15)
]
/**1.遍历**/
students.each {
println it.value.toString()
}
/**带索引遍历**/
students.eachWithIndex{ Map.Entry<Integer, Stu> entry, int i ->
println "index:$i key:$entry.key value:$entry.value "
}
groovy中查找提供了find
和findAll
方法,用法如下:
//find查找一项
def stu1 = students.find {
it.value.age>12
}
println stu1.value
//findAll查找所有项
def stus = students.findAll {
it.value.age>12
}
//count:统计个数
def stuCount = students.count {
it.value.age>12
}
//多重查找
def stu2 = students.findAll {
it.value.age>12
}.collect {
it.value.name
}
使用groupBy
关键字
def group = students.groupBy {
return it.value.age>12?"大":"小"
}
使用sort
def sort = students.sort {student1,student2 ->
student1.value.age == student2.value.age?0:student1.value.age < student2.value.age?-1:1
}
全部0条评论
快来发表一下你的评论吧 !