Groovy腳本高級(jí)特征總結(jié)

      網(wǎng)友投稿 1192 2022-05-29

      上一篇博文提到,Groovy是一種基于JVM,功能強(qiáng)大、類型可選、動(dòng)態(tài)的,可與Java無縫銜接的編程語言。該語言易于學(xué)習(xí),可以大大提高開發(fā)人員的工作效率,可為Java程序添加強(qiáng)大的功能,其中就包含腳本功能(scripting capabilities)。合理的使用腳本特征功能,可以大大提高程序的靈活性,這非常適合做一些補(bǔ)丁功能,或者個(gè)性化極強(qiáng)的功能,比如促銷活動(dòng),這個(gè)活動(dòng)規(guī)則會(huì)經(jīng)常的變動(dòng),因此,如果不借助某種機(jī)制,當(dāng)促銷規(guī)則發(fā)生變化時(shí),則需要重新進(jìn)行編碼調(diào)整并發(fā)布程序,這樣的程序維護(hù)起來過于麻煩。

      針對(duì)類似促銷規(guī)則多變的編程場(chǎng)景,用腳本引擎來實(shí)現(xiàn)規(guī)則的維護(hù)和運(yùn)行,是一種很好的方案。由于腳本本質(zhì)上就是一段文本代碼,因此,可以非常方便的在后臺(tái)進(jìn)行及時(shí)的維護(hù),當(dāng)運(yùn)行時(shí),則加載并運(yùn)行新腳本即可實(shí)現(xiàn)新促銷方案的發(fā)布工作。本篇就重點(diǎn)對(duì)腳本特征進(jìn)行介紹。

      根據(jù)官方的介紹,Groovy語言提供了多種機(jī)制,可以很好的與Java語言或者Groovy本身進(jìn)行腳本特征的整合工作。官方的文檔地址為:https://docs.groovy-lang.org ,可根據(jù)需要自行閱讀相關(guān)文檔進(jìn)行學(xué)習(xí)。

      首先,在Groovy語言框架中,提供了一個(gè)groovy.util.Eval 類,可以動(dòng)態(tài)的執(zhí)行腳本,它的使用也非常的簡(jiǎn)單,其中有一個(gè)Eval.me方法,可執(zhí)行腳本。下面給出示例代碼:

      import groovy.util.Eval y = Eval.me('2.5 * 3') println y //7.5 println Eval.x(7, '2*x') // 14 println Eval.xyz(3, 2, 6, 'x*y+z') //12 println Eval.me('m', 3, 'm**2') //9

      從示例代碼中可知,首先需要導(dǎo)入包,然后就可以用Eval.me或者其他方法來實(shí)現(xiàn)簡(jiǎn)單的腳本執(zhí)行。特別的,它支持動(dòng)態(tài)參數(shù)功能,如一個(gè)表達(dá)式中參數(shù)x,y,z,那么可以使用Eval.xyz()方法來執(zhí)行。

      注意:Eval類執(zhí)行腳本是沒有緩存功能的,且不適合處理多行的腳本。因此只適合于簡(jiǎn)單的腳本執(zhí)行。

      其次,在Groovy語言框架中,還提供了一個(gè)groovy.lang.GroovyShell類,也可以動(dòng)態(tài)的執(zhí)行腳本,它可以對(duì)腳本進(jìn)行緩存,并處理多種數(shù)據(jù)來源的腳本,如多行文本String,文件File,Reader和InputStream等。下面給出示例代碼:

      def shell = new GroovyShell() def y = shell.evaluate '2.5 * 3' println y // 7.5 y = shell.evaluate(new StringReader('2.5 * 3')) println y // 7.5 def script = shell.parse '2.5 * 3' println script instanceof groovy.lang.Script //true println script.run() // 7.5 /////////////////////////// def sharedData = new Binding() def shell = new GroovyShell(sharedData) sharedData.setProperty('name', 'Jack') sharedData.setProperty('age', 33) //Jack age is 33 println shell.evaluate('"$name age is $age"') shell.evaluate('x = 7') println sharedData.getProperty('x') //7 //顯性類型,局部變量,無法外部訪問 shell.evaluate('int y = 7') println sharedData.getProperty('y') //Exception //def局部變量,無法外部訪問 shell.evaluate('def z = 7') println sharedData.getProperty('z') //Exception /////////////////////////// def shell = new GroovyShell() shell.evaluate('x = 7') shell.evaluate('y = 2 * x') println shell.evaluate('"$y"') //14

      注意:共享變量是全局變量,多線程下是有點(diǎn)問題的,不是線程安全的。

      Groovy腳本高級(jí)特征總結(jié)

      除此外,GroovyShell下還有一個(gè)parse方法,也可以支持腳本特征,示例如下:

      def shell = new GroovyShell() def b1 = new Binding(x:3) def script1 = shell.parse('x = 2*x ; x = x + 1;def sum(x,y){return x+y};x = sum(x,1)') script1.binding = b1 script1.run() println b1.getProperty('x') //8

      從示例中可知,它可以解析多條語句,用分號(hào)分隔,并支持函數(shù)定義等。

      其次,還有一種就是groovy.lang.GroovyClassLoader類,可以更加靈活的執(zhí)行腳本,示例如下:

      import groovy.lang.GroovyClassLoader def cloader = new GroovyClassLoader() def clazz = cloader.parseClass('class Utils { void say(String msg) { println "Hello,"+msg } }') println clazz.name // Utils def o = clazz.newInstance() o.say("Jack") //Hello,Jack //////////////////////////// import groovy.lang.GroovyClassLoader def gcl = new GroovyClassLoader() def clazz1 = gcl.parseClass('class Utils { void say(String msg) { println "Hello,"+msg } }') def clazz2 = gcl.parseClass('class Utils { void say(String msg) { println "Hello,"+msg } }') println clazz1 == clazz2 //false ///////////////////////////////////// def clazz3 = gcl.parseClass(new File("K:\\Utils.groovy")) def clazz4 = gcl.parseClass(new File("K:\\Utils.groovy")) println clazz3 == clazz4 //true

      注意:GroovyClassLoader默認(rèn)會(huì)引用所有創(chuàng)建的類對(duì)象,且文本定義的類,即使是同名的,也是不同的對(duì)象,因此,同樣的腳本,多次執(zhí)行會(huì)創(chuàng)建多個(gè)對(duì)象,可能會(huì)導(dǎo)致內(nèi)存泄漏。當(dāng)采用File傳入腳本后,Groovy可以緩存同一個(gè)文件腳本,并只創(chuàng)建同一個(gè)對(duì)象。

      最后,還有一個(gè)groovy.util.GroovyScriptEngine類,也可以支持腳本特征,它的功能更加的強(qiáng)大和靈活。它是建立在GroovyClassLoader類之上,可以處理類的依賴問題以及重加載的問題,即可以實(shí)現(xiàn)熱更新功能。示例如下:

      def binding = new Binding() def engine = new GroovyScriptEngine("K:\\") while (true) { //Demo02.groovy 文件名不能和類名Demo一致,否則類重復(fù) def utils = engine.run('Demo02.groovy', binding) println utils.say("Jack") Thread.sleep(500) } //Demo02.groovy class Demo { String say(String msg) { "Hello, $msg" //"Hello2, $msg" } } new Demo()

      Groovy Java

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔(dān)相應(yīng)法律責(zé)任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實(shí)的內(nèi)容,請(qǐng)聯(lián)系我們jiasou666@gmail.com 處理,核實(shí)后本網(wǎng)站將在24小時(shí)內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:ModelArts問題索引_old
      下一篇:測(cè)試從零開始-No.2-了解計(jì)算機(jī)基礎(chǔ)知識(shí)
      相關(guān)文章
      亚洲AV无码成人精品区天堂| 国产AV无码专区亚洲AV麻豆丫| 在线观看亚洲网站| 亚洲精品亚洲人成在线播放| 亚洲AV乱码久久精品蜜桃| 亚洲国产精品无码久久久蜜芽 | 久久精品国产亚洲AV无码偷窥| 亚洲AV无码1区2区久久| 亚洲日本一区二区三区| 亚洲av永久无码精品网站| 亚洲色精品vr一区二区三区 | 亚洲成AV人片在线观看| 亚洲AV无码专区在线播放中文 | 亚洲综合无码一区二区| 亚洲国产成人久久精品动漫| 麻豆亚洲AV永久无码精品久久| 久久久久亚洲AV无码观看| 亚洲精品456在线播放| 亚洲成a人片在线观| 亚洲妇女熟BBW| 亚洲色最新高清av网站| 亚洲国产精品成人AV在线| 在线观看亚洲视频| 久久久久亚洲爆乳少妇无| 亚洲精品无码鲁网中文电影| 亚洲国产精品一区第二页| 91大神亚洲影视在线| 亚洲一区二区三区亚瑟| 亚洲人成人无码.www石榴| 亚洲AV噜噜一区二区三区| 亚洲精品麻豆av| 国产AV无码专区亚洲AVJULIA| 亚洲欧洲国产日韩精品| 亚洲色偷偷偷网站色偷一区| 国产成人精品日本亚洲网址| 含羞草国产亚洲精品岁国产精品| 亚洲精品亚洲人成在线观看下载| 国产亚洲免费的视频看 | 亚洲国产精品成人网址天堂| 亚洲色婷婷一区二区三区| 91精品国产亚洲爽啪在线影院|