Groovy學(xué)習(xí)目錄-傳送門
ConfigSlurper
ConfigSlurper
是一個用于讀取以Groovy腳本形式定義的配置文件的實用程序類碟刺。 類似于Java * .properties
文件的情況,ConfigSlurper
允許使用點符號。 但此外,它允許Closure作用域配置值和任意對象類型珊擂。
def config = new ConfigSlurper().parse('''
app.date = new Date() //點符號的用法
app.age = 42
app { //使用Closure作用域作為點符號的替代
name = "Test${42}"
}
''')
assert config.app.date instanceof Date
assert config.app.age == 42
assert config.app.name == 'Test42'
從上面的例子可以看出唧垦,parse
方法可以用來檢索groovy.util.ConfigObject
實例撒桨。ConfigObject
是一個專門的java.util.Map
實現(xiàn),它返回配置的值或一個新的ConfigObject
實例墨坚,但永遠不為null
秧饮。
def config = new ConfigSlurper().parse('''
app.date = new Date()
app.age = 42
app.name = "Test${42}"
''')
assert config.test != null//`config.test`還沒有被指定,它被調(diào)用時返回一個`ConfigObject`。
在點符號
是配置變量名稱的一部分的情況下浦楣,可以使用單引號或雙引號對其進行轉(zhuǎn)義袖肥。
def config = new ConfigSlurper().parse('''
app."person.age" = 42
''')
assert config.app."person.age" == 42
此外,ConfigSlurper
還支持environments
振劳。 environments
方法可以用來移交一個本身可能由幾個部分組成的Closure
實例椎组。 假設(shè)我們想為開發(fā)環(huán)境創(chuàng)建一個特定的配置值。 當(dāng)創(chuàng)建ConfigSlurper實例時历恐,我們可以使用ConfigSlurper(String)
構(gòu)造函數(shù)來指定目標環(huán)境寸癌。
def config = new ConfigSlurper('development').parse('''
environments {
development {
app.port = 8080
}
test {
app.port = 8082
}
production {
app.port = 80
}
}
''')
assert config.app.port == 8080
ConfigSlurper
環(huán)境不限于任何特定的環(huán)境名稱。 它只依賴于ConfigSlurper
客戶端代碼支持和解釋什么值弱贼。
environments
方法是內(nèi)置的蒸苇,但registerConditionalBlock
方法可用于注冊除environments
名稱之外的其他方法名稱。
def slurper = new ConfigSlurper()
slurper.registerConditionalBlock('myProject', 'developers') //一旦新block被注冊吮旅,ConfigSlurper可以解析它溪烤。
def config = slurper.parse('''
sendMail = true
myProject {
developers {
sendMail = false
}
}
''')
assert !config.sendMail
對于Java集成,toProperties
方法可用于將ConfigObject
轉(zhuǎn)換為可能存儲到* .properties
文本文件的java.util.Properties
對象庇勃。 請注意檬嘀,將配置值添加到新創(chuàng)建的Properties
實例時,將其轉(zhuǎn)換為String
實例责嚷。
def config = new ConfigSlurper().parse('''
app.date = new Date()
app.age = 42
app {
name = "Test${42}"
}
''')
def properties = config.toProperties()
assert properties."app.date" instanceof String
assert properties."app.age" == '42'
assert properties."app.name" == 'Test42'
Expando
Expando
類可用于創(chuàng)建動態(tài)可擴展對象鸳兽。 盡管它的名稱叫Expando罕拂,它不使用類ExpandoMetaClass
衷掷。 每個Expando
對象表示一個獨立的動態(tài)制作的實例棍鳖,可以在運行時使用屬性(或方法)進行擴展。
def expando = new Expando()
expando.name = 'John'
assert expando.name == 'John'
當(dāng)動態(tài)屬性注冊Closure
代碼塊時,會發(fā)生特殊情況醇份。 一旦Closure
被注冊僚纷,它就可以被調(diào)用怖竭,因為它將通過方法調(diào)用完成哮肚。
def expando = new Expando()
expando.toString = { -> 'John' }
expando.say = { String s -> "John says: ${s}" }
assert expando as String == 'John'
assert expando.say('Hi') == 'John says: Hi'
可觀察的 list, map and set
Groovy帶有可觀察的 list, map and set鸦致。 當(dāng)添加分唾,刪除或更改元素時,每個集合都會觸發(fā)java.beans.PropertyChangeEvent
事件。 注意,PropertyChangeEvent
不僅發(fā)出某個事件已經(jīng)發(fā)生的信號睹逃,此外,它保存關(guān)于屬性名稱和某個屬性已經(jīng)改變到的舊/新值的信息。
根據(jù)發(fā)生的更改的類型猎荠,可觀察的集合可能觸發(fā)更專門的PropertyChangeEvent
類型荒叶。 例如些楣,向可觀察列表中添加元素會觸發(fā)ObservableList.ElementAddedEvent
事件。
def event //聲明一個PropertyChangeEventListener捕獲被觸發(fā)的事件
def listener = {
if (it instanceof ObservableList.ElementEvent) { //ObservableList.ElementEvent及其子類型與此偵聽器相關(guān)
event = it
}
} as PropertyChangeListener
def observable = [1, 2, 3] as ObservableList //注冊監(jiān)聽器
observable.addPropertyChangeListener(listener) //從給定列表創(chuàng)建一個ObservableList
observable.add 42 //觸發(fā)ObservableList.ElementAddedEvent事件
assert event instanceof ObservableList.ElementAddedEvent
def elementAddedEvent = event as ObservableList.ElementAddedEvent
assert elementAddedEvent.changeType == ObservableList.ChangeType.ADDED
assert elementAddedEvent.index == 3
assert elementAddedEvent.oldValue == null
assert elementAddedEvent.newValue == 42
請注意,添加元素實際上會觸發(fā)兩個事件。 第一個是類型 ObservableList.ElementAddedEvent
,第二個是一個普通的PropertyChangeEvent
,通知監(jiān)聽器屬性size
的更改。
ObservableList.ElementClearedEvent
事件類型是另一個有趣的事件類型秫筏。 每當(dāng)刪除多個元素時田轧,例如調(diào)用clear()
時巷查,它保存從列表中刪除的元素有序。
def event
def listener = {
if (it instanceof ObservableList.ElementEvent) {
event = it
}
} as PropertyChangeListener
def observable = [1, 2, 3] as ObservableList
observable.addPropertyChangeListener(listener)
observable.clear()
assert event instanceof ObservableList.ElementClearedEvent
def elementClearedEvent = event as ObservableList.ElementClearedEvent
assert elementClearedEvent.values == [1, 2, 3]
assert observable.size() == 0
為了獲得所有支持的事件類型的概述,我們鼓勵讀者查看JavaDoc文檔或正在使用的observable集合的源代碼岛请。
ObservableMap
和ObservableSet
帶有我們在本節(jié)中對ObservableList
所看到的相同的概念旭寿。