前言:
大家回想一下自己第一次接觸Gradle
是什么時候?
相信大家也都是和我一樣,在我們打開第一個AS項(xiàng)目的時候,
發(fā)現(xiàn)有很多帶gradle字樣的文件:setting.gradle, build.gradle,gradle.warpper
,以及在gradle
文件中各種配置,
這些都是啥wy啊。。
特別對于一些小公司開發(fā)人員,因?yàn)榻佑|架構(gòu)層面的機(jī)會很少,可能在使用AS幾年后都不一定對Gradle
有太多深入了解,這是實(shí)話,因?yàn)楣P者就是這么過來的。。
而Gradle
又是進(jìn)階高級
開發(fā)的必經(jīng)之路。
好了,接下來進(jìn)入正題,此系列筆者會由淺入深的方式,帶領(lǐng)大家來了解下,Gradle
背后究竟有哪些奧秘。
Gradle`定義:
很多開發(fā)喜歡把Gradle
簡單定義為一種構(gòu)建工具,和ant,maven
等作用類似,
誠然Gradle確實(shí)是用來做構(gòu)建,但是如果簡單得把Gradle拿來做構(gòu)建,就太小看Gradle了.
筆者更愿意將Gradle看做一種編程框架
。在這個框架中,你可以做很多ant,maven等常用構(gòu)建工具做不了的事情,
如將自己的任務(wù)task集成到構(gòu)建生命周期中,完成文件拷貝,腳本編寫等操作。
Gradle
優(yōu)缺點(diǎn):
相較早期的構(gòu)建工具:ant,maven等。
優(yōu)點(diǎn)如下:
-
1.使用DSL Grovvy語言來編寫: :了解ant的同學(xué)應(yīng)該都知道:ant使用的是xml配置的模式,而Gradle使用的是
表達(dá)性的Groovy
來編寫,Groovy同時
支持面向?qū)ο蠛兔嫦蜻^程
進(jìn)行開發(fā),這個特性讓Groovy
可以寫出一些腳本的任務(wù),這在傳統(tǒng)ant,maven上是不可能實(shí)現(xiàn)的 -
2.基于java虛擬機(jī): :
Groovy
是基于jvm
的語言,groovy
文件編譯后其實(shí)就是class文件,和我們的java
一樣。
所以在gradle構(gòu)建過程中,我們完全可以使用java/kotlin去編寫我們的構(gòu)建任務(wù)以及腳本,極大的降低我們學(xué)習(xí)的成本。
- 3.Gradle自定義task :可以構(gòu)建自己的任務(wù),然后掛接到gradle構(gòu)建
生命周期
中去,這在ant,maven上也是不可能實(shí)現(xiàn)的, - 4.擴(kuò)展性好 :gradle將關(guān)鍵配置扔給我們開發(fā)者,開發(fā)者配置好任務(wù)后,無需關(guān)心gradle是如何構(gòu)建的。
缺點(diǎn):
用過gradle都知道,低版本gradle的項(xiàng)目在高版本的gradle中經(jīng)常出現(xiàn)很多莫名其妙的錯誤,
向后兼容性較差
。
介紹了那么多,下面正式來講解今天的主角:Groovy
Groovy
語法詳解
因?yàn)槲覀兊腉roovy和java很類似,所以這里我們以和java的差異性進(jìn)行展開,這樣可以更好的去理解groovy語法
1.編程方式
java
:面向?qū)ο?/p>
groovy
:面向?qū)ο蠛瓦^程
groovy不僅可以和java一樣面向?qū)ο筮M(jìn)程編程,也可以創(chuàng)建面向過程的腳本開發(fā):
package variable
int i1 = 1
double d1 = 1
println(i1.class)
println(d1.class)
2.語法簡潔
-
2.1:
分號
:groovy默認(rèn)行尾不加分號 -
2.3:
setter/getter
:groovy默認(rèn)給我們類內(nèi)部屬性,創(chuàng)建setter和getter方法,外部只需要使用屬性名訪問即可 -
2.4:
字符串
:groovy支持三種類型的字符串表達(dá)式定義-
單引號
:不能使用+號代替,如果你確定這個字符串只是使用,不會更改那么你可以這么定義//單引號定義不可更改內(nèi)容 def s1 = 's1' //使用轉(zhuǎn)移字符://s'a'2 def s2 = 's\\'a\\'2'
-
雙引號
:在字符串內(nèi)部可以使用{2+3}"
-
三引號:支持自動換行
一般我們會使用前兩種,最后一種很少用
-
-
2.5:使用弱聲明:
def
,編譯過程會自動類型檢測,這個屬性和kotlin的val/var
很像。java
def str = "this is groovy str"
3.方法
3.1: 方法定義
groovy中:使用def聲明方法的返回值,如果沒有返回值,則默認(rèn)返回一個null
def echo(){
return "echo this"
}
3.2:方法參數(shù):
groovy傳入的參數(shù)可以省略參數(shù)類型,且可以設(shè)置參數(shù)默認(rèn)值,有默認(rèn)值調(diào)用的時候可以省略帶默認(rèn)值的參數(shù)
def echo(message,name = '123'){
return "echo:"+message +name
}
調(diào)用:echo("hello groovy")
3.3:方法返回值
使用return返回,如果省略return,則返回的是最后方法最后一行
def echo(){
"echo this"
}
println echo()
結(jié)果:"echo this"
3.4:方法調(diào)用流程
groovy方法調(diào)用不像我們java,其內(nèi)部給我們創(chuàng)建了很多判斷的分支,支持在運(yùn)行期動態(tài)添加方法
下面是groovy方法調(diào)用流程圖:
gradle方法.png
- 3.4.1:
invokeMethod
:對于類中所有調(diào)用方法:包括已定義和未定義方法,都會走到這個invokeMethod方法中,需要實(shí)現(xiàn):GroovyInterceptable
接口這個方法可以在我們方法執(zhí)行器做一些方法類型參數(shù)等判斷
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"
}
}
調(diào)用:
def per = new Person(name: 'lily')
println per.helloGroovy()
println per.helloGroovy1()
結(jié)果:
this method name is helloGroovy
this method name is helloGroovy1
可以看到所有的方法都被分派到invokeMethod且沒有執(zhí)行后續(xù)流程:這個和我們java運(yùn)行期動態(tài)代理模式
有點(diǎn)類似,我們可以在invokeMethod
中實(shí)現(xiàn)一些AOP
的架構(gòu),如打印所有方法的統(tǒng)一日志
等。
- 3.4.2:
methodMissing
:對于未定義的方法,如果重寫這個methodMissing,則會調(diào)用這個方法Object methodMissing(String name, Object args) { println "methodMissing : $name" }
最新版本groovy未發(fā)現(xiàn)這個方法,應(yīng)該是被去掉了 。不過這個對于我們開發(fā)關(guān)系不大
- 3.4.3:
元編程metaClass
:可以在運(yùn)行期注入屬性和方法包括靜態(tài)方法,這個特性就比較厲害了,對于一些第三方類庫,可以使用這個方式在運(yùn)行期動態(tài)創(chuàng)建方法,相當(dāng)于對類庫進(jìn)行了一次擴(kuò)展
學(xué)習(xí)過kotlin的都知道:擴(kuò)展函數(shù)和擴(kuò)展屬性,差不多是這個用法
注入屬性:
class Person implements{
def name
def age
}
//注入屬性
Person.metaClass.sex = 'male'
def person1 = new Person(name: 'yuhb',age: 29)
println person1.sex
結(jié)果:male
注入方法:
//注入方法,使用閉包
Person.metaClass.sexUpperCase = { ->
sex.toUpperCase()
}
println person1.sexUpperCase()
結(jié)果:MALE
4.集合
4.1:集合分類
groovy中集合有三種:
列表List
:對應(yīng)java中的List
def list = [1, 2, 3, 4,5,6]
映射Map
:對應(yīng)java中的Map
def map = [key1:'value',key2:'value2']
注意:map中的key默認(rèn)都是String類型的字符串,即使我們自己沒加,編譯器也會給我們加上
范圍Range
:groovy中獨(dú)有
def range = [1..100]
range其實(shí)就是指定了一個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 = "優(yōu)"
break
default:
result = "不確定"
break
}
result
}
4.2:集合遍歷
所有集合都可以使用each
和eachWithIndex
進(jìn)行遍歷,當(dāng)然也可以使用java中的for循環(huán),但在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 "
}
4.3:查找
groovy中查找提供了find
和findAll
方法,用法如下:
//find查找一項(xiàng)
def stu1 = students.find {
it.value.age>12
}
println stu1.value
//findAll查找所有項(xiàng)
def stus = students.findAll {
it.value.age>12
}
//count:統(tǒng)計(jì)個數(shù)
def stuCount = students.count {
it.value.age>12
}
//多重查找
def stu2 = students.findAll {
it.value.age>12
}.collect {
it.value.name
}
4.4:分組:
使用groupBy
關(guān)鍵字
def group = students.groupBy {
return it.value.age>12?"大":"小"
}
4.5:排序:
使用sort
def sort = students.sort {student1,student2 ->
student1.value.age == student2.value.age?0:student1.value.age < student2.value.age?-1:1
}
-
JAVA
+關(guān)注
關(guān)注
19文章
2970瀏覽量
104814 -
開發(fā)
+關(guān)注
關(guān)注
0文章
370瀏覽量
40861 -
gradle
+關(guān)注
關(guān)注
0文章
26瀏覽量
726
發(fā)布評論請先 登錄
相關(guān)推薦
評論