Ⅰ Groovy腳本實現輕量級規則引擎
1) 當業務規則變更時,對應的代碼也得跟著更改,每次即使是小的變更都需要經歷開發、測試驗證上線等過程,變更成本比較大。
2) 長時間系統變得越來越難以維護。
3) 開發團隊一般是由一個熟悉業務的BA(業務分析人員)和若干個熟悉技術的開發人員組成,開發人員對業務規則的把握能力遠不及BA,但實際上卻承擔了將業務規則准確無誤實現的重任。
4) 系統僵化,新需求插入困難。
5) 新需求上線周期較長。
規則引擎由推理引擎發展而來,是一種嵌入在應用程序中的組件,實現了 將業務決策從應用程序代碼中分離出來 ,並使用預定義的語義模塊編寫業務決策。接受數據輸入,解釋業務規則,並根據業務規則做出業務決策。
把規則和核心業務拆開, 規則單獨配置 。這樣當我們的規則變化的時候,就可以通過修改規則文件而 不用修改核心的代碼 了。
在 規則較為復雜的行業 ,都是適用的,如金融、製造、醫療、物流等行業,面臨的規則變化較為復雜,目前使用較多。而且對規則引擎需求的行業也將越來越多,如團購平台、傳統企業管理渠道等。
JBoss Drools Rete演算法
Mandarax
JLisa
OpenRules
JEOPS
InfoSapient
JRuleEngine
Roolie
Rete 模式匹配演算法是在模式匹配中利用推理機的時間冗餘性和規則結構的相似性, 通過保存中間去處來提高推理效率的一種模式匹配演算法。
在模式匹配過程中, 規則的前提中可能會有很多相同的模塊, 因此在匹配規則前提時, 將進行大量的重復運算, 這樣就帶來時間冗餘性問題。例如:
RULE1:if (A>B) and D or C then E=100
RULE2:if (A>B) and (BB) or (BB 要進行三次計算, 對B B, M2=B
Ⅱ 利用groovy腳本獲取soapui中請求和響應的值
例如如下數據,calendar_id是需要根據返回值動態獲取的,此時需要通過獲得數組中的calendar_id
{"calendar":
[
{"calendar_id":"1705","showtime":"1288927800","endshowtime":"1288931400","allDay":false},
{"calendar_id":"1706","showtime":"1288933200","endshowtime":"1288936800","allDay":false},
{"calendar_id":"1709","showtime":"1288935600","endshowtime":"1288938900","allDay":false}
]
}
在SoapUI中可以通過groovy腳本實現提取json數組數據,提取到數據後就可以遍歷訪問列表中的每條新聞正文了
1.新建一個REST請求步驟,獲取介面返回的數據
2.新建一個DataSource步驟,選擇Groovy方式
3.添加一個名為cal_id的Properties
4.groovy編輯框中輸入實現代碼
[java] view plain
import groovy.json.JsonSlurper
def xresponse = testRunner.testCase.testSteps["getCalendarListByCoid"].testRequest.response.contentAsString
def slurper = new JsonSlurper()
def re = slurper.parseText(xresponse)
def num=re.calendar.size()
def i = testRunner.testCase.testSteps["DataSource"].currentRow
if(i<num)
{
result["cal_id"]=String.valueOf(re.calendar_id.id[i])
}
5.新建一個Property Transfer步驟,將DataSource的cal_id傳遞給當前testCase的變數
6.新建 一個REST請求步驟,將得到的cal_id去請求另一個介面
7.新建一個DataSource Loop步驟,使DataSource與Property Transfer步驟循環,這樣就可以遍歷數組中的每個數據了
[reply]tz0705010216[/reply]
你好
以博文中的json為例,新增的groovy步驟則如下:
def xresponse = testRunner.testCase.testSteps["getCalendarListByCoid"].testRequest.response.contentAsString
def slurper = new JsonSlurper()
def re = slurper.parseText(xresponse)
def id = re.calendar.calendar_id[i] //i為json數組中的第i個子json對象
若為在腳本斷言處添加groovy斷言,則如下:
def xresponse = messageExchange.modelItem.testCase.testSteps["getCalendarListByCoid"].testRequest.response.contentAsString
def slurper = new JsonSlurper()
def result = slurper.parseText(xresponse)
def id = re.calendar.calendar_id[i] //i為json數組中的第i個子json對象
Ⅲ 如何在groovy腳本定義全局變數
例如,我們經常需要對一個字元串進行如下的判斷: if(str!=null&&!str.equals("")) { ...... }輸入這樣的語句的確使人生厭,而且有時候還會忘掉輸入「!str.equals("")」語句中的「!」導致代碼出現邏輯錯誤。
Ⅳ Groovy基本語法
官方文檔
和Java一樣,支持單行(使用 // )、多行( /* */ )和文檔注釋(使用 /** */ )。
UNIX系統支持一種特殊的單行注釋叫作 Shebang line ,用於指明腳本的運行環境,這樣就可以直接在終端中使用 ./xxx.groovy 運行(當然,前提是文件得有可運行的許可權),而不用像 groovy xxx.groovy 這樣運行:
# 號必須是文件的第一個字元。
以字母、美元符號 $ 或下劃線 _ 開始,不能以數字開始。以下是可用的標識符:
以下是不可用的標識符:
注意:在點號後,是可以使用關鍵字作為標識符的:
Groovy在點表達式(dotted expression)後面可以使用引號標識符,比如 persion.name 可以表示為 persion.'name' 或 persion."name" 。而引號中可以包含普通標識符中不支持的字元,比如空格、中檔線 - 這些:
其實,Groovy支持多種字元串的字面量表達形式,這些都是可以出現在點號後面的:
更方便的是,Groovy中的 GString 支持 插值 ,也可以用在點號後面的:
在Groovy中字元串有兩種類型,一種是Java原生的 java.lang.String ;另一種是 groovy.lang.GString ,又叫 插值字元串 (interpolated strings)。
在Groovy中,使用單引號括住的字元串就是 java.lang.String ,不支持插值:
使用三單引號括住字元串支持多行,也是 java.lang.String 實例,在第一個 』『』 起始處加一個反斜杠 可以在新一行開始文本:
如果雙引號括住的字元串中沒有插值表達式(interpolated expression),那它就是 java.lang.String ;如是有插值表達式,那它就是 groovy.lang.GString :
在Groovy所有的字元串字面量表示中,除了單引號字元串和三單引號字元串,其他形式都支持字元串插值。字元串插值,也即將佔位表達式中的結果最終替換到字元串相應的位置中:
當使用點號表達式時,可以只用 $ 代替 ${} :
插值佔位符中還支持閉包,而閉包的一個好處是 惰性求值 (lazy evaluation):
當一個方法的需要一個 java.lang.String 變數,而我們傳遞的是一個 groovy.lang.GString 實例時, GString 的 toString 方法會被自動調用,看起來像我們可以直接將一個 GString 賦值給一個 String 變數一樣。
注意: GString 與 String 的hashCode是不一樣的,即使他們最終結果一樣。所以,在Map中,不應該用 GString 去做元素的Key,而又使用普通的 String 去取值:
類似於三單引號字元串,但支持字元串插值。
除了使用引號來括住字元串,還可以使用 / 。它一般用來定義正則表達式:
這種字元串使用 $/ 開始,使用 /$ 結束,其中的轉義字元為 $ :
在Groovy中並沒有明確的字元字面量表示形式,我們必須明確指明:
當使用 def 指明整數字面量時,變數的類型會根據數字的大小自動調整:
為了精確地計算小數,在Groovy中使用 def 聲明的小數是 BigDecimal 類型的:
如果要強制指明一個數字的字面量類型,可以給字面量加上類型後綴:
默認情況下Groovy的列表使用的是 java.util.ArrayList ,用中括弧 [] 括住,使用逗號分隔:
如果要使用其它類型的列表(如: LinkedList )可以使用 as 操作符或顯式分配給一個指定類型的變數:
Groovy重載了列表的 [] 和 << 操作符,可以通過 List[index] 訪問指定位置元素,也可以通過 List << element 往列表末尾添加元素:
在Groovy中,沒有數組的字面量定義方式。和特定類型列表的定義方式一樣,我們需要使用 as 操作符或顯式地分配給一個數組類型的變數:
Groovy使用中括弧 [] 來定義映射,元素需要包含key和value使用冒號分隔,元素與元素之間用逗號分隔:
在上邊的例子中,雖然沒有明確的使用字元串 』red『 、 』green『 ,但Groovy會自動把那些key轉化為字元串。並且,在默認情況下,初始化映射時,key也不會去使用已經存在的變數:
如果要使用一個變數作為key,需要用括弧括住:
Ⅳ groovy腳本中字元串怎樣拼空格
Groovy字元串及其常用方法
字元串方法
與java不同,在GString中提供了多種表示字元串的方法,分別是單引號字元串、雙引號字元串、三單引號字元串、三雙引號字元串、斜杠字元串和$修飾的斜杠字元串。
單引號字元串
單引號字元串是一系列被單引號包圍的字元,是普通的java.lang.String。不支持插值。
def str = 'groovy'
assert str.class == java.lang.String
三單引號字元串
三單引號字元串是一列被三個單引號包圍的字元,是普通的java.lang.String。不支持插值。
def str = '''groovy'''
assert str.class == java.lang.String
三單引號字元串是多行的。你可以使字元串內容跨越行邊界,不需要將字元串分割為一些片段,不需要連接,或換行轉義符:
def str = '''
one
two
three'''
//需要注意的是,這個字元串每一次換行都包含了一個換行轉義符:
assert str.contains("\n") == true
assert str.size() == 14
//可以通過使用反斜杠換行符剝離該字元
def str = '''\
one\
two\
three'''
assert str.contains("\n") == false
assert str.size() == 11
Ⅵ 什麼是 Groovy
● 是一個基於 Java虛擬機的敏捷 動態語言。 ● 構建在強大的Java語言之上 並 添加了從Python,Ruby和Smalltalk等語言中學到的 諸多特徵。 ●為Java開發者提供了 現代最流行的編程語言特性,而且學習成本很低(幾乎為零)。 ● 支持DSL(Domain Specific Languages領域定義語言)和其它簡潔的語法,讓你的代碼變得易於閱讀和維護。 ● Groovy擁有處理原生類型,面向對象以及一個Ant DSL,使得創建Shell Scripts變的非常簡單。 ● 在開發Web,GUI,資料庫或控制台程序時 通過 減少框架性代碼 大大提高了開發者的效率。 ● 支持單元測試和模擬(對象),可以 簡化測試。 ● 無縫集成 所有已經存在的 Java對象和類庫。 ● 直接編譯成Java位元組碼,這樣可以在任何使用Java的地方 使用Groovy。 Groovy 的一個好處是,它的語法與 Java 語言的語法很相似。雖然 Groovy 的語法源於 Smalltalk 和 Ruby 這類語言的理念,但是可以將它想像成 Java 語言的一種更加簡單、表達能力更強的變體。(在這點上,Ruby 與 Groovy 不同,因為它的語法與 Java 語法差異很大。) Groovy 快捷方式 開始使用 Groovy 時,您會發現它使日常的編程活動變得快了許多。完成本教程之後,您會了解更多的 Groovy 語法快捷方式。不過現在只需知道以下這些要點: Groovy 的鬆散的 Java 語法允許省略分號和修改符。 除非另行指定,Groovy 的所有內容都為 public。 Groovy 允許定義簡單腳本,同時無需定義正規的class 對象。 Groovy 在普通的常用 Java 對象上增加了一些獨特的方法和快捷方式,使得它們更容易使用。 Groovy 語法還允許省略變數類型。 Groovy 的新增特性 雖然Groovy 允許省略 Java 語法中的一些元素,但也增加了一些新特性,例如本地集合、內置的正則表達式和閉包。在標準的 Java 代碼中,如果想要創建一個項列表,首先要導入<code>java.util.ArrayList</code>,然後程序化地初始化 <code>ArrayList</code> 實例,然後 再向實例中添加項。在 Groovy 中,列表和映射都內置在語法中 — 無需導入任何內容。正則表達式也不需要額外的導入或對象;它們可以通過特殊的 Groovy 語法來創建。 關於閉包 對於任何 Java 開發人員來說,閉包都是一個令人興奮的新技巧。這些神奇的構造將會包含在未來的 Java 發行版(很可能是 Java 7)中,成為正式的 Java 語法,但現在已經可以在 Groovy 中使用了。可以將閉包 想像為一個代碼塊,可以現在定義,以後再執行。可以使用這些強大的構造做許多漂亮的事,不過最著名的是簡化迭代。使用 Groovy 之後,就有可能再也不需要編寫Iterator 實例了。 動態的 Groovy 從技術上講,Groovy 可能是您最近聽說過的類型最鬆散的動態語言之一。從這個角度講,Groovy 與 Java 語言的區別很大,Java 語言是一種固定類型語言。在 Groovy 中,類型是可選的,所以您不必輸入String myStr = "Hello"; 來聲明 String 變數,可以使用def myStr = "Hello";(分號可有可無)。 除此之外,Groovy 代碼還能在運行時輕松地改變自己。這實際上意味著,能夠在運行時輕松地為對象指定新方法和屬性。這一編程領域稱為元編程,Groovy 能夠很好地支持這種編程方式。在學習本教程的過程中,您將了解到關於 Groovy 的動態性質的更多內容。現在惟一要補充的是,您會驚訝地發現,在 Groovy 會使操作 XML 或普通的 java.io.File 實例變得非常輕松。 一體兩面 用Groovy 編寫的任何內容都可以編譯成標準的 Java 類文件並在 Java 代碼中重用。類似地,用標准 Java 代碼編寫的內容也可以在 Groovy 中重用。所以,可以輕易地使用 Groovy 為 Java 代碼編寫單元測試。而且,如果用 Groovy 編寫一個方便的小工具,那麼也可以在 Java 程序中使用這個小工具。 Groovy是用Java實現的開源腳本語言並且和它聯系緊密.它需要JDK 1.4. Groovy向Java添加了許多Ruby和Python腳本語言的特性. Groovy的特性包括動態類型(dynamic typing), 閉包(closures),簡單對象導航( easy object navigation)和更加簡潔的Lists和Maps語法. Groovy是由James Strachan和Bob McWhirter創造的. James還參與了許多其他開源項目的開發,其中包括Jelly, dom4j, Jaxen, Betwixt和Maven. Bob是Jaxen和Drools (一個開源的面向對象的JAVA規則引擎) 的創始人. 目前最新穩定版為Groovy1.8。
Ⅶ 在java中使用groovy怎麼搞
一種基於Java虛擬機的動態語言,可以和java無縫集成,正是這個特性,很多時候把二者同時使用,把groovy作為java的有效補充。對於Java程序員來說,學習成本幾乎為零。同時支持DSL和其他簡介的語法(例如閉包),使代碼便於閱讀。可以用groovy的動態特性來做規則引擎,在DB中維護腳本,業務變化的時候讓應用系統動態載入。
如果引入groovy在java工程中?
這個很簡單,不需要做別的事情,僅僅把groovy的二方包加入到pom文件中即可。例如:
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version> 1.8 . 3 </version>
</dependency>
java和groovy混合使用的方法有幾種?
1、 靜態編譯 ,在java工程中直接寫groovy的文件,然後可以在groovy的文件中引用java工程的類,這種方式能夠有效的利用groovy自身的語言特性,例如閉包;
2、通過 groovyShell 類直接執行腳本,例如:
package groovy_dsl.shell;
import groovy.lang.Binding;
import groovy.lang.GroovyShell;
public class GroovyShellEx {
public static void main(String[] args) {
Binding bind = new Binding();
bind.setVariable( "name" , "iamzhongyong" );
bind.setVariable( "age" , "25" );
GroovyShell shell = new GroovyShell(bind);
Object obj = shell.evaluate( "str = name+age;return str" );
System.out.println(obj);
}
}
3、通過 groovyScriptEngine 執行文件或者腳本,例如:
package groovy_dsl.script;
import groovy.util.GroovyScriptEngine;
public class ScriptEngine {
public static void main(String[] args) throws Exception {
GroovyScriptEngine engine = new GroovyScriptEngine( "" );
Object obj = engine.run( "src/main/java/groovy_dsl/script/script_test.groovy" , "iamzhongyong" );
System.out.println(obj);
}
}
4、通過 GroovyClassLoader 來執行,例如:
package groovy_dsl.classloader;
import groovy.lang.GroovyClassLoader;
import groovy.lang.GroovyObject;
import java.io.File;
import java.io.IOException;
public class GroovyClassLoaderEx {
public static void main(String[] args) throws Exception, IOException {
GroovyClassLoader loader = new GroovyClassLoader();
for ( int i= 0 ;i< 100 ;i++){
Class<?> clazz = loader.parseClass( new File( "src/main/java/groovy_dsl/classloader/UserDO.groovy" ));
GroovyObject clazzObj = (GroovyObject)clazz.newInstance();
clazzObj.invokeMethod( "setName" , "iamzhongyong" );
clazzObj.invokeMethod( "setSex" , "Boy" );
clazzObj.invokeMethod( "setAge" , "26" );
System.out.println(clazzObj.invokeMethod( "getAllInfo" , null ));
}
}
}
使用groovy尤其需要主要的問題?
通過看groovy的創建類的地方,就能發現,每次執行的時候,都會新生成一個class文件,這樣就會導致JVM的perm區持續增長,進而導致FullGCc問題,解決辦法很簡單,就是腳本文件變化了之後才去創建文件,之前從緩存中獲取即可。
groovy中的源碼如下:
return parseClass(text, "script" + System.currentTimeMillis() + Math.abs(text.hashCode()) + ".groovy" );
這個是增加緩存的代碼:
GroovyClassLoader groovyClassLoader = new GroovyClassLoader(GroovyScriptExecute. class .getClassLoader());
Class<?> groovyClass = null ;
String classKey = String.valueOf(scriptClass.hashCode());
//先從緩存裡面去Class文件
if (GroovyScriptClassCache.newInstance().containsKey(classKey)){
groovyClass = GroovyScriptClassCache.newInstance().getClassByKey(classKey);
} else {
groovyClass = groovyClassLoader.parseClass(scriptClass);
GroovyScriptClassCache.newInstance().putClass(classKey, groovyClass);
}
GroovyObject go = (GroovyObject)groovyClass.newInstance();
下面這個是緩存的單例類,貼一下:
public class GroovyScriptClassCache {
private static final Map<String /*class文件的描述*/ ,Class<?>> GROOVY_SCRIPT_CLASS_CACHE = new HashMap<String,Class<?>>();
private GroovyScriptClassCache(){}
private static GroovyScriptClassCache instance = new GroovyScriptClassCache();
public static GroovyScriptClassCache newInstance(){
return instance;
}
public Class<?> getClassByKey(String key){
return GROOVY_SCRIPT_CLASS_CACHE.get(key);
}
public void putClass(String key,Class<?> clazz){
GROOVY_SCRIPT_CLASS_CACHE.put(key, clazz);
}
public boolean containsKey(String key){
return GROOVY_SCRIPT_CLASS_CACHE.containsKey(key);
}
}
為啥要每次new一個GroovyClassLoader,而不是所有的腳本持有一個?
因為如果腳本重新載入了,這時候就會有新老兩個class文件,如果通過一個classloader持有的話,這樣在GC掃描的時候,會認為老的類還在存活,導致回收不掉,所以每次new一個就能解決這個問題了。
注意CodeCache的設置大小
對於大量使用Groovy的應用,尤其是Groovy腳本還會經常更新的應用,由於這些Groovy腳本在執行了很多次後都會被JVM編譯為native進行優化,會占據一些CodeCache空間,而如果這樣的腳本很多的話,可能會導致CodeCache被用滿,而CodeCache一旦被用滿,JVM的Compiler就會被禁用,那性能下降的就不是一點點了。
Code Cache用滿一方面是因為空間可能不夠用,另一方面是Code Cache是不會回收的,所以會累積的越來越多(其實在不採用groovy這種動態更新/裝載class的情況下的話,是不會太多的),所以解法一可以是增大code cache的size,可通過在啟動參數上增加-XX:ReservedCodeCacheSize=256m(Oracle JVM Team那邊也是推薦把code cache調大的),二是啟用code cache的回收機制(關於Code Cache flushing的具體策略請參見此文),可通過在啟動參數上增加:-XX:+UseCodeCacheFlushing來啟用。
Ⅷ jenkins執行groovy 腳本報錯
Jenkins下安裝groovy 插件:
編寫groovy腳本:
Execute Groovy script'執行報錯了,java.io.IOException: Cannot run program "groovy" (in directory "D:\Program Files (x86)\Jenkins\workspace\*******"): CreateProcess error=2, 系統找不到指定的文件。原因是Jenkins沒有配置groovy的安裝.
Manage Jenkins->Global Tool Configuration:
再次執行成功:
Ⅸ 六、ElasticSearch之groovy腳本執行partial update
es,其實是有個內置的腳本支持的,可以基於groovy腳本實現各種各樣的復雜操作。
基於groovy腳本,如何執行partial update
准備數據
(1)內置腳本
(2)外部腳本,放在es的config/scripts下
(3)用腳本刪除文檔
(4)upsert操作
Ⅹ groovy語言主要是用來干什麼,和JAVA的區別是什麼
Groovy是Java平台上設計的面向對象編程語言。這門動態語言擁有類似Python、Ruby和Smalltalk中的一些特性,可以作為Java平台的腳本語言使用。 groovy的語法跟java完全按類似。
它和java的區別是:
一:java為強類型的語言;Groovy為弱類型,可以自動推斷類型;
創建數組的時候Groovy的語法為:def intArray=[2,3,4]
創建MAP的時候Groovy的語法為:def m={}
二:Groovy默認訪問修飾符為Public,可以不寫訪問修飾符
可以直接用def關鍵字定義,如:
def sayHello(){}
限定訪問范圍
@PackageScope修飾方法