漫話規(guī)則引擎(4): Java規(guī)則引擎規(guī)范:JSR94
本文最新版已更新至:http://thinkinside.tk/2012/12/07/jsr94.html
漫話規(guī)則引擎(4): Java規(guī)則引擎規(guī)范:JSR94
Java World似乎總會(huì)出現(xiàn)一些接口規(guī)范,這樣做的好處是可以面向接口編程,可以在實(shí)現(xiàn)了該接口的產(chǎn)品/組件之間自由切換,避免被廠商綁架。 本文要介紹的JSR94:Java Rule Engine API,Java規(guī)則引擎API規(guī)范。
Table of Contents
1 概述
JSR-94是JCP(Java Community Process)制定的關(guān)于Java規(guī)則引擎API的規(guī)范,包括接口定義和示例代碼。于2004年8月發(fā)布。 JSR-94定義了javax.rules和javax.rules.admin,前者包含了Java規(guī)則引擎運(yùn)行時(shí)(Rumtime)API及異常(Exception)定義,后者包含了規(guī)則管理相關(guān)的API和異常定義。
2 規(guī)則管理API
規(guī)則管理API在javax.rules.admin中定義,主要包括以下類/接口:

| 類/接口 | 說明 |
|---|---|
| Rule | 規(guī)則實(shí)體 |
| RuleExecutionSet | 執(zhí)行集,某個(gè)規(guī)則對應(yīng)的動(dòng)作 |
| LocalRuleExecutionSetProvider | 用于從本地創(chuàng)建執(zhí)行集,如InputStream,Reader等 |
| RuleExectuionSetProvider | 用于從本地或遠(yuǎn)程創(chuàng)建執(zhí)行集,如xml Element,Serializable等 |
| RuleAdministrator | 用于獲取ExecutionSetProvider,并管理執(zhí)行集的注冊/注銷 |
規(guī)則管理API實(shí)現(xiàn)的功能包括:
- 裝載規(guī)則(Rule)和執(zhí)行集(RuleExecutionSet)
- 執(zhí)行集的注冊/注銷,只有注冊的執(zhí)行集對應(yīng)的規(guī)則才能被客戶訪問
3 運(yùn)行時(shí)API
運(yùn)行時(shí)API在javax.rules中定義,主要包括以下類/接口:

| 類/接口 | 說明 |
|---|---|
| RuleServiceProviderManager | 通過URL注冊/注銷RuleServiceProvider |
| RuleServiceProvider | 提供對RuleRuntime和RuleAdministrator的訪問 |
| RuleRuntime | 規(guī)則引擎運(yùn)行時(shí),可以創(chuàng)建規(guī)則會(huì)話 |
| RuleSession | 規(guī)則會(huì)話,用于執(zhí)行規(guī)則 |
| RuleExecutionSetMetaData | 執(zhí)行集元數(shù)據(jù),包括name,url,description等。執(zhí)行集元數(shù)據(jù)會(huì)被RuleSession使用 |
| StatelessRuleSession | 無狀態(tài)規(guī)則會(huì)話 |
| StatefulRuleSession | 有狀態(tài)規(guī)則會(huì)話 |
| Handle和ObjectFilter | 有狀態(tài)會(huì)話維護(hù)會(huì)話狀態(tài)的幫助類 |
規(guī)則引擎運(yùn)行時(shí)API實(shí)現(xiàn)的功能包括:
- 注冊/注銷規(guī)則引擎實(shí)例,只有注冊的規(guī)則引擎實(shí)例才能被使用
- 從注冊的規(guī)則引擎實(shí)例創(chuàng)建Runtime
- 從Runtime創(chuàng)建會(huì)話,包括有狀態(tài)和無狀態(tài)兩種會(huì)話
- 通過會(huì)話執(zhí)行規(guī)則
4 異常定義
除了前面提到的主要類/接口外,JSR94還規(guī)定了規(guī)則引擎運(yùn)行時(shí)及管理的一些異常,如下:

5 代碼示例
下面是使用Drools作為規(guī)則引擎實(shí)例的一個(gè)例子,規(guī)則文件使用了Drools的drl格式:
JSR94Sample.java
package com.sample; import java.io.FileReader; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import javax.rules.ConfigurationException; import javax.rules.RuleRuntime; import javax.rules.RuleServiceProvider; import javax.rules.RuleServiceProviderManager; import javax.rules.StatelessRuleSession; import javax.rules.admin.LocalRuleExecutionSetProvider; import javax.rules.admin.RuleAdministrator; import javax.rules.admin.RuleExecutionSet; import org.drools.jsr94.rules.RuleServiceProviderImpl; public class JSR94Sample { private static RuleServiceProvider ruleProvider; private static void initProvider(){ String uri = RuleServiceProviderImpl.RULE_SERVICE_PROVIDER; Class providerClass = RuleServiceProviderImpl.class; try{ //注冊ruleProvider RuleServiceProviderManager.registerRuleServiceProvider(uri, providerClass); //從RuleServiceProviderManager獲取ruleProvider ruleProvider = RuleServiceProviderManager.getRuleServiceProvider(uri); }catch(ConfigurationException e){ e.printStackTrace(); } } private static void adminSample(){ try{ //獲取RuleAdministrator實(shí)例 RuleAdministrator admin = ruleProvider.getRuleAdministrator(); //獲取RuleExectuionSetProvider HashMap properties = new HashMap(); properties.put("name", "My Rules"); properties.put("description", "A trivial rulebase"); LocalRuleExecutionSetProvider ruleExecutionSetProvider = admin.getLocalRuleExecutionSetProvider(properties); //創(chuàng)建RuleExecutionSet FileReader reader = new FileReader("bin/sample.drl"); RuleExecutionSet reSet = ruleExecutionSetProvider.createRuleExecutionSet(reader, properties); //注冊RuleExecutionSet admin.registerRuleExecutionSet("mysample",reSet,properties); }catch(Exception e){ e.printStackTrace(); } } private static void runtimeSampe(){ try{ //獲取RuleRuntime, 創(chuàng)建會(huì)話 RuleRuntime runtime = ruleProvider.getRuleRuntime(); StatelessRuleSession ruleSession = (StatelessRuleSession)runtime.createRuleSession("mysample",null,RuleRuntime.STATELESS_SESSION_TYPE); //初始化輸入數(shù)據(jù) Message message1 = new Message(); message1.setMessage("Hello World"); message1.setStatus(Message.HELLO); Message message2 = new Message(); message2.setMessage("Goodbye World"); message2.setStatus(Message.GOODBYE); List inputs = new ArrayList(); inputs.add(message1); inputs.add(message2); //執(zhí)行規(guī)則 List<Message> results = ruleSession.executeRules(inputs); for(int i=0;i<results.size();i++){ Message msg = results.get(i); System.out.println(msg.message); } //釋放會(huì)話資源 ruleSession.release(); }catch(Exception e){ e.printStackTrace(); } } public static void main(String[] args) { // TODO Auto-generated method stub initProvider(); adminSample(); runtimeSampe(); } public static class Message { public static final int HELLO = 0; public static final int GOODBYE = 1; private String message; private int status; public String getMessage() { return this.message; } public void setMessage(String message) { this.message = message; } public int getStatus() { return this.status; } public void setStatus(int status) { this.status = status; } } }
規(guī)則文件使用的就是在這里使用的例子。
6 實(shí)現(xiàn)JSR94的產(chǎn)品
主要的一些實(shí)現(xiàn)了JSR94的規(guī)則引擎產(chǎn)品如下:
| 產(chǎn)品 | 商業(yè)/開源 | 規(guī)則描述語言 | 算法 | 規(guī)則開發(fā)工具 | 規(guī)則保存 | 部署方式 |
|---|---|---|---|---|---|---|
| Drools | 開源 | DRL,xDRL,DSL,Decision Table | ReteOO | Eclipse,excel | 文件系統(tǒng) | jar |
| Mandarax | 開源 | RuleML | ||||
| OpenRules | 開源 | Decision Table | Rete | excel | war | |
| JLisa | 開源 | |||||
| Blaze | 商業(yè) | SRL | ||||
| WebSphere ILOG JRules | 商業(yè) | |||||
| JESS | 商業(yè) |
7 小結(jié)
JSR94為規(guī)則引擎提供了公用標(biāo)準(zhǔn)API,為實(shí)現(xiàn)規(guī)則管理API和運(yùn)行時(shí)API提供了指導(dǎo)規(guī)范, 目前已經(jīng)獲得很多開源/商業(yè)規(guī)則引擎產(chǎn)品的支持。 但是JSR94沒有對規(guī)則的描述語言進(jìn)行規(guī)范,導(dǎo)致各規(guī)則引擎產(chǎn)品大多采用自己私有的描述語言。
Date: 2012-12-07 12:49:16 CST
HTML generated by org-mode 6.33x in emacs 23

浙公網(wǎng)安備 33010602011771號