Groovy中怎么構(gòu)建DSL,針對(duì)這個(gè)問題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡(jiǎn)單易行的方法。
站在用戶的角度思考問題,與客戶深入溝通,找到增城網(wǎng)站設(shè)計(jì)與增城網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、外貿(mào)網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊(cè)、網(wǎng)絡(luò)空間、企業(yè)郵箱。業(yè)務(wù)覆蓋增城地區(qū)。
官方定義是“Groovy中的閉包是一個(gè)開放,匿名的代碼塊,可以接受參數(shù),返回值并分配給變量”
簡(jiǎn)而言之,他說一個(gè)匿名的代碼塊,可以接受參數(shù),有返回值。在DSL中,一個(gè)DSL腳本就是一個(gè)閉包。
比如:
//執(zhí)行一句話 { printf 'Hello World' } //閉包有默認(rèn)參數(shù)it,且不用申明 { println it } //閉包有默認(rèn)參數(shù)it,申明了也無所謂 { it -> println it } // name是自定義的參數(shù)名 { name -> println name } //多個(gè)參數(shù)的閉包 { String x, int y -> println "hey ${x} the value is ${y}" }
每定義的閉包是一個(gè)Closure對(duì)象,我們可以把一個(gè)閉包賦值給一個(gè)變量,然后調(diào)用變量執(zhí)行
//閉包賦值 def closure = { printf("hello") } //調(diào)用 closure()
當(dāng)調(diào)用的方法需要參數(shù)時(shí),Groovy 不要求使用括號(hào),若有多個(gè)參數(shù),那么參數(shù)之間依然使用逗號(hào)分隔;如果不需要參數(shù),那么方法的調(diào)用必須顯示的使用括號(hào)。
def add(number) { 1 + number } //DSL調(diào)用 def res = add 1 println res
也支持級(jí)聯(lián)調(diào)用方式,舉例來說,a b c d
實(shí)際上就等同于 a(b).c(d)
//定義 total = 0 def a(number) { total += number return this } def b(number) { total *= number return this } //dsl a 2 b 3 println total
我們結(jié)合 Groovy 中對(duì)屬性的訪問就是對(duì) getXXX 的訪問,將無參數(shù)的方法名改成 getXXX 的形式,即可實(shí)現(xiàn)“調(diào)用無參數(shù)的方法不需要括號(hào)”的語法!比如:
def getTotal() { println "Total" } //DSL調(diào)用 total
MOP:元對(duì)象協(xié)議。由 Groovy 語言中的一種協(xié)議。該協(xié)議的出現(xiàn)為元編程提供了優(yōu)雅的解決方案。而 MOP 機(jī)制的核心就是 MetaClass。
有點(diǎn)類似于 Java 中的反射,但是在使用上卻比 Java 中的反射簡(jiǎn)單的多。
常用的方法有:
invokeMethod()
setProperty()
hasProperty()
methodMissing()
以下是一個(gè)methodMissing的例子:
detailInfo = [:] def methodMissing(String name, args) { detailInfo[name] = args } def introduce(closure) { closure.delegate = this closure() detailInfo.each { key, value -> println "My $key is $value" } } introduce { name "zx" age 18 }
@BaseScript
需要在注釋在自定義的腳本類型變量上,來指定當(dāng)前腳本屬于哪個(gè)Delegate,從而執(zhí)行相應(yīng)的腳本命令,也使IDE有自動(dòng)提示的功能:
腳本定義 abstract class DslDelegate extends Script { def setName(String name){ println name } }
腳本:
import dsl.groovy.SetNameDelegate import groovy.transform.BaseScript @BaseScript DslDelegate _ setName("name")
使用以上介紹的方法,只能在腳本里執(zhí)行單個(gè)命令,如果想在腳本里執(zhí)行復(fù)雜的嵌套關(guān)系,比如Gradle中的dependencies,就需要@DelegatesTo支持了,@DelegatesTo執(zhí)行了腳本里定義的閉包用那個(gè)類來解析。
上面提到一個(gè)DSL腳本就是一個(gè)閉包,這里的DelegatesTo其實(shí)定義的是閉包里面的二級(jí)閉包的格式,當(dāng)然如果你樂意,可以無限嵌套定義。
//定義二級(jí)閉包格式 class Conf{ String name int age Conf name(String name) { this.name = name return this } Conf age(int age) { this.age = age return this } } //定義一級(jí)閉包格式,即腳本的格式 String user(@DelegatesTo(Conf.class) Closure<Conf> closure) { Conf conf = new Conf() DefaultGroovyMethods.with(conf, closure) println "my name is ${conf.name} my age is ${conf.age}" } //dsl腳本 user{ name "tom" age 12 }
腳本可以在IDE里直接執(zhí)行,大多數(shù)情況下DSL腳本都是以文本的形式存在數(shù)據(jù)庫或配置中,這時(shí)候就需要先加載腳本再執(zhí)行,加載腳本可以通過以下方式:
CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); compilerConfiguration.setScriptBaseClass(DslDelegate.class.getName()); GroovyShell shell = new GroovyShell(GroovyScriptRunner.class.getClassLoader()); Script script = shell.parse(file);
給腳本傳參數(shù),并得到返回結(jié)果:
Binding binding = new Binding(); binding.setProperty("key", anyValue); Object res = InvokerHelper.createScript(script.getClass(), binding).run()
關(guān)于Groovy中怎么構(gòu)建DSL問題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識(shí)。
網(wǎng)站標(biāo)題:Groovy中怎么構(gòu)建DSL
網(wǎng)頁URL:http://jinyejixie.com/article42/ggggec.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供做網(wǎng)站、網(wǎng)站制作、電子商務(wù)、網(wǎng)站建設(shè)、網(wǎng)站營銷、商城網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)