基于Java注解的Drools業務規則開發框架設計實現
規則引擎由推理引擎發展而來,是一種嵌入在應用程序中的組件,實現了將業務決策從應用程序代碼中分離出來,并使用預定義的語義模塊編寫業務決策。規則引擎接受數據輸入,解釋業務規則,并根據業務規則做出業務決策。規則引擎適用于業務規則復雜且頻繁改動的系統。
Drools是RedHat公司旗下一款基于Java語言的開源規則引擎,廣泛應用于金融、保險、電信等領域,可以將復雜多變的規則以規則腳本的形式存放在文件中,使得規則的變更不需要重啟機器就可以立即在線上環境生效。
在業務規則開發過程中,Drools規則引擎只能識別與處理基于DRL(Domain Rule Language)格式定義的業務邏輯,與Java程序相比存在著一些缺陷,不能很好地支持企業級應用管理,主要表現在以下兩方面。
(1)開發效率待提高:DRL語法學習成本較高;傳統Java開發環境(例如Eclipse)不支持對DRL進行語法檢查和語法輔助,無法在運行前發現語法錯誤;部分規則文件無法進行調試;重構難度大,進行規則修改時很難評估影響范圍。
(2)代碼質量缺乏保障:無法通過代碼質量管理工具(例如SonarQube)對DRL文件進行檢查與分析。
為解決這些缺陷,迫切需要建立Drools業務規則開發框架,直接使用Java語言實現業務邏輯,單元測試通過后自動生成Drools業務規則。
Drools業務規則開發框架主要由編寫模塊、執行模塊、轉換模塊三部分組成。其中編寫模塊定義Java語言實現業務邏輯的規范;執行模塊對Java語言實現的業務邏輯模擬執行,并支持在傳統Java開發環境中進行代碼調試;轉換模塊將Java語言實現的業務邏輯轉換成Drools規則引擎支持的業務規則。
Drools業務規則開發框架的使用流程如圖1所示。

圖1 Drools業務規則開發框架的使用流程
通過使用此開發框架,技術人員直接使用Java語言實現業務邏輯,將極大提高開發效率和代碼質量。
下面介紹Drools業務規則開發框架的實現技術。
2.1 Java注解技術
注解(annotation)是JDK1.5及以后版本引入的一個特性。注解(annotation)是一個接口,程序可以通過反射來獲取指定程序元素的注解對象,然后通過注解對象來獲取注解里面的元數據。
元注解(meta-annotation)的作用是負責注解其他注解。Java5.0定義了4個標準的元注解類型,它們被用來提供對其它 注解類型作說明。其中元注解@Target說明了注解所修飾的對象范圍,元注解@Retention定義了該注解被保留的時間長短,分為三種情況:SOURCE表示出現在源代碼中但被編譯器丟棄;CLASS表示編譯在class文件中但在class文件裝載時被忽略;RUNTIME表示編譯在class文件中且在class裝載時被讀取。
Java注解技術對于Drools業務規則開發框架至關重要。基于注解技術,執行模塊獲取代碼中的元注解信息從而動態執行Java代碼,轉換模塊獲取代碼中的元注解信息從而完成代碼分析從而轉換為DRL文件。
2.2 編寫模塊
編寫模塊中定義了三種注解,分別為RuleGroup、Rule、RuleFunction,這三種注解的@Retention都設置為RUNTIME,以便在執行模塊及轉換模塊中獲取注解信息。
RuleGroup標識在規則流中所屬的節點,定義如下:
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface RuleGroup {
String ruleflowGroup();
}
Rule標識業務規則屬性,如優先級。定義如下:
@Target({ ElementType.TYPE })
@Retention(RetentionPolicy.RUNTIME)
public @interface Rule {
String salience() default "10000";
}
RuleFunction標識業務規則中調用的函數方法。定義如下:@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
public @interface RuleFunction {
}
基于這三種注解,使用Java語言編寫的業務邏輯示例如下:@RuleGroup(ruleflowGroup="RequestRules")
public class RequestRules {
@Rule(salience = "10000")
public static class Rule1 {
public boolean when() { return true;
}
public void then() {
func1();
}
}
@RuleFunction
static void func1() {
}
}
從以上示例可以看到,技術人員使用Java語言實現業務邏輯,能夠進行語法檢查和語法輔助,也能通過代碼質量管理工具保證代碼的規范性。
2.3 執行模塊
執行模塊采用反射技術加載Java語言編寫的業務邏輯并執行,處理流程如圖2所示。

圖2 執行模塊處理流程圖
具體處理流程如下:
(1)按規則流節點順序加載使用RuleGroup注解的類;
(2)獲取類中使用Rule注解的內部類并按salience排序;(3)按順序執行各內部類;
①實例化內部類innerRule;
②如果innerRule.when()結果為true則執行inner Rule.then(),否則回到①實例化下一個內部類。
業務規則when部分的輸入為字符串,輸出為true或false,類似于Javascript中的eval()函數。執行模塊采用規則引擎加載此字符串并執行,核心代碼如下:
// 加載DRL并執行
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory. newKnowledgeBuilder();
kbuilder add(ResourceFactory newReaderResource(strReade r),ResourceType.DRL);
KnowledgeBase kbase = kbuilder.newKnowledgeBase();
StatefulKnowledgeSession ksession = kbase. newStatefulKnowledgeSession();
ksession insert(messageWrapper);
QueryResults results = ksession.getQueryResults(drlHash);
// 對執行結果進行判斷
return (results.size() > 0);
2.4 轉換模塊
轉換模塊將Java文件轉換為Drools規則引擎支持的DRL文件,處理流程如圖3所示。

圖3 轉換模塊處理流程圖
具體處理流程如下:
(1)按規則流節點順序加載Java文件;
(2)使用開源的google JavaParser庫進行Java文件解析;
(3)對使用Rule注解的內部類進行循環處理,獲取ruleflow-group屬性、salience屬性、when部分、then部分及function部分;
(4)將生成的符合Drools業務規則語法的字符串寫入DRL文件。
從全球民航發展情況看,由于市場競爭不斷加劇,全球民航業長期處于微利運營水平。在日益艱難的市場環境中,國內外航空公司在客運方面力圖沖破只能提供航空運輸的傳統服務模式,不斷探索新的商務模式和盈利渠道,正在發展成為以航空運輸為中心、集酒店、租車、旅游、免稅品銷售等服務于一體的航空旅游綜合服務提供商[4]。航空公司機票+酒店動態打包銷售平臺項目(簡稱動態打包項目)正是在這個大背景下立項并實施的。
在開發動態打包項目時,采用了Drools規則引擎,基于規則流(RuleFlow)技術實現動態打包查詢、預訂、取消等功能,輸入輸出遵循OTA(Open Travel Alliance)國際標準。
在實現中,將輸入輸出抽象為MessageWrapper,將每個功能的業務處理流程進行總結,抽象為RequestRules、SwitchingRules、AggregationRules、ResponseOptionRules、ResponseRules共5個節點,分別實現請求校驗、外部系統調用、外部系統結果合并、響應結果過濾與排序、響應結果處理(如促銷價格計算)功能。節點名稱與RuleGroup中的ruleflowGroup屬性相對應。每個節點內的業務規則按優先級順序執行,整體業務處理流程如圖4所示。

圖4 業務處理流程圖
為驗證開發框架在提高開發效率方面的效果,項目組選取動態打包查詢模塊進行比對實驗。選取兩個水平接近的開發人員,以通過預先設定的單元測試為完成標準,采用直接編寫DRL文件的開發方式共花費15人天,采用開發框架共花費11人天。
根據以上比對實驗,通過使用Drools業務規則開發框架,動態打包項目提高開發效率20%以上,節省至少5人月開發工作量。同時在SonarQube中代碼質量評級為A,取得預期效果。
利用基于Java注解的Drools業務規則開發框架,技術人員可以方便的進行業務規則編寫、調試,提升代碼質量,提高開發效率。
動態打包項目中每個節點內的業務規則按優先級順序執行,沒有涉及規則的重復觸發與沖突檢測,后續還需要持續改進完善。
[1]張淵,夏清國.基于Rete算法的JAVA規則引擎[J].科學技術與工程,2006,6(11) :1548-1550.
[2]李春芳,譚慶平. 面向業務的 Drools規則引擎改進[J]. 計算機應用與軟件,2015,32(5) :20-23.
[3]凌晨,陳芳莉.Java注釋類型和APT [J]. 計算機系統應用,2006,15(9):78-82.
[4]王欣明,呂明站.民航附加服務動態打包技術研究[J]. 民航科技,2011(3):39-42.
[5]繳明洋,譚慶平. Java規則引擎技術研究[J]. 計算機與信息技術,2006(3) :44-46.
周中雨(1978——),男,河北省河間市,中級工程師,碩士研究生,主要從事J2EE平臺軟件架構設計及研發。
李洋(1977——),男,陜西省藍田縣,中級工程師,碩士研究生,主要從事J2EE平臺軟件架構設計及研發。
王懷超(1984——),男,天津,講師,博士研究生,主要研究方向航空物流、計算機視覺。
楊程屹(1986——),男,河北省灤縣,中級工程師,博士研究生,主要從事數據挖掘、算法研究等工作。
周中雨1,李洋1,楊程屹1,王懷超2
(1.中國民航信息網絡股份有限公司,北京,100105;2.中國民航大學計算機科學與技術學院,天津,300300)
本文設計并實現了基于Java注解的規則引擎Drools業務規則開發框架。該開發框架針對Drools業務規則存在的無法語法檢查、無法調試等問題,基于Java注解技術,直接使用Java語言實現業務邏輯,單元測試通過后生成Drools業務規則,從而提升代碼質量并提高開發效率。
規則引擎;Drools;業務規則;Java注解;Java反射
Design and Implementation on Framework for Developing Drools Business Rules Based on Java Annotation
Zhou Zhongyu1,Li Yang1,Yang Chengyi1,Wang Huaichao2
(1.Travelsky Technology Limited,Beijing,100105;2.College of Computer Science and Technology, Civil Aviation University of China,Tianjin,300300)
We design and implement a framework for developing Drools business rules based on Java annotation in order to solve the problems such as absence of syntax checking, difficulty of debugging, etc. Using the framework developers implement business logic in Java language and translate Java files to Drools business rules after passing the unit test The framework is designed to improve code quality and efficiency
Rule Engine;Drools;Business Rules;Java Annotation;Java Reflect
2013年民航科技創新引導項目(MHRD20130216)。