规则引擎简介

Java规则引擎是推理引擎的一种,它起源于基于规则的专家系统。       Java规则引擎将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。Java规则引擎接受数据输入,解释业务规则,并根据规则作出业务决策。从这个意义上来说,它是软件方法学在"关注点分离"上的一个重要的进展。       JSR-94规范定义了独立于厂商的标准API,开发人员可以通过这个标准的API使用Java规则引擎规范的不同产品实现。但值得注意的是,这个规范并没有强制统一规则定义的语法,因此,当需要将应用移植到其他的Java规则引擎实现时,可能需要变换规则定义。

基于规则的专家系统(RBES)

专家系统是人工智能的一个分支,它模仿人类的推理方式,使用试探性的方法进行推理,并使用人类能理解的术语解释和证明它的推理结论。专家系统有很多分类:神经网络、基于案例推理和基于规则系统等。        规则引擎则是基于规则的专家系统的一部分。为了更深入的了解Java规则引擎,下面简要地介绍基于规则的专家系统(RBES)。

RBES的技术架构

RBES包括三部分:Rule Base(knowledge base)、Working Memory(fact base)和Rule Engine(推理引擎)。它们的结构如下所示:

 
图1.基于规则的专家系统组成  
       如上图所示,规则引擎包括三部分:Pattern Matcher、Agenda和Execution Engine。Pattern Matcher决定选择执行哪个规则,何时执行规则;Agenda管理PatternMatcher挑选出来的规则的执行次序;Execution Engine负责执行规则和其他动作。
 

RBES的推理(规则)引擎

和人类的思维相对应,规则引擎存在两者推理方式:演绎法(Forward-Chaining)和归纳法(Backward-Chaining)。演绎法从一个初始的事实出发,不断地应用规则得出结论(或执行指定的动作)。而归纳法则是从假设出发,不断地寻找符合假设的事实。        Rete算法是目前效率最高的一个Forward-Chaining推理算法,Drools项目是Rete算法的一个面向对象的Java实现。        规则引擎的推理步骤如下:        1. 将初始数据(fact)输入Working Memory。        2. 使用Pattern Matcher比较规则(rule)和数据(fact)。        3. 如果执行规则存在冲突(conflict),即同时激活了多个规则,将冲突的规则放入冲突集合。        4. 解决冲突,将激活的规则按顺序放入Agenda。        5. 使用规则引擎执行Agenda中的规则。重复步骤2至5,直到执行完毕所有Agenda中的规则。

 
JSR-94:Java规则引擎API        基于规则编程是一种声明式的编程技术,这种技术让你可以使用试探性的规则而不是过程性的指令来解决问题。规则引擎是一个软件模块,它决定了如何将规则作用于推理数据。在保险业和金融服务业都广泛地使用了基于规则的编程技术,当需要在大量的数据上应用复杂的规则时,规则引擎技术特别有用。        Java规则引擎API由javax.rules包定义,是访问规则引擎的标准企业级API。Java规则引擎API允许客户程序使用统一的方式和不同厂商的规则引擎产品交互,就像使用JDBC编写独立于厂商访问不同的数据库产品一样。Java规则引擎API包括创建和管理规则集合的机制,在Working Memory中添加,删除和修改对象的机制,以及初始化,重置和执行规则引擎的机制。
使用Java规则引擎API        Java规则引擎API把和规则引擎的交互分为两类:管理活动和运行时活动。管理活动包括实例化规则引擎和装载规则。而运行时活动包括操作Working Memory和执行规则。如果你在J2SE环境中使用Java规则引擎,你可能需要在代码中执行以上所有的活动。相反,在J2EE环境中,Java规则引擎的管理活动是应用服务器的一部分。JSR 94的参考实现包括了一个JCA连接器,用于通过JNDI获得一个RuleServiceProvider。
设置规则引擎        Java规则引擎的管理活动阶段开始于查找一个合适的javax.rules.RuleServiceProvider对象,这个对象是应用程序访问规则引擎的入口。在J2EE环境中,你可能可以通过JNDI获得RuleServiceProvider。否则,你可以使用javax.rules.RuleServiceProviderManager类:

String implName = "org.jcp.jsr94.ri.RuleServiceProvider";
Class.forName(implName);
RuleServiceProvider serviceProvider = RuleServiceProviderManager.getRuleServiceProvider(implName);
       一旦拥有了RuleServiceProvider对象,你可以获得一个javax.rules.admin.RuleAdministrator类。从RuleAdministrator类中,你可以得到一个RuleExecutionSetProvider,从类名可以知道,它用于创建javax.rules.RuleExecutionSets对象。RuleExecutionSet基本上是一个装入内存的,准备好执行的规则集合。        包javax.rules.admin包括两个不同的RuleExecutionSetProvider类。RuleExecutionSetProvider类本身包括了从Serializable对象创建RuleExecutionSets的方法,因此在规则引擎位于远程服务器的情况下,仍然可以使用RuleExecutionSetProvider类,构造器的参数可以通过RMI来传递。另一个类是LocalRuleExecutionSetProvider,包含了其他方法,用于从非Serializable资源(如java.io.Reader-本地文件)创建RuleExectionSets。假设拥有了一个RuleServiceProvider对象,你可以从本地文件rules.xml文件创建一个RuleExectionSet对象。如以下的代码所示:

          RuleAdministrator admin = serviceProvider.getRuleAdministrator();
HashMap properties = new HashMap();
properties.put("name", "My Rules");
properties.put("description", "A trivial rulebase");
FileReader reader = new FileReader("rules.xml");
RuleExecutionSet ruleSet = null;
try {
LocalRuleExecutionSetProvider lresp =
admin.getLocalRuleExecutionSetProvider(properties);
ruleSet = lresp.createRuleExecutionSet(reader, properties);
} finally {
reader.close();
}
       接下来,你可以使用RuleAdministrator注册获得的RuleExecutionSet,并给它分配一个名称。在运行时,你可以用同一个名称创建一个RuleSession;该RuleSession使用了这个命名的RuleExecutionSet。参见下面的例子: admin.registerRuleExecutionSet("rules", ruleSet, properties);
执行规则引擎        在运行时阶段,你可以参见一个RuleSession对象。RuleSession对象基本上是一个装载了特定规则集合的规则引擎实例。你从RuleServiceProvider得到一个RuleRuntime对象,接下来,从javax.rules.RuleRuntime得到RuleSession对象。        RuleSession分为两类:stateful和stateless。它们具有不同的功能。StatefulRuleSession的Working Memory能够在多个方法调用期间保存状态。你可以在多个方法调用期间在Working Memory中加入多个对象,然后执行引擎,接下来还可以加入更多的对象并再次执行引擎。相反,StatelessRuleSession类是不保存状态的,为了执行它的executeRules方法,你必须为Working Memory提供所有的初始数据,执行规则引擎,得到一个内容列表作为返回值。        下面的例子中,我们创建一个StatefulRuleSession实例,添加两个对象(一个Integer和一个String)到Working Memory,执行规则,然后得到Working Memory中所有的内容,作为java.util.List对象返回。最后,我们调用release方法清理RuleSession:          RuleRuntime runtime = rsp.getRuleRuntime();          StatefulRuleSession session = (StatefulRuleSession)          runtime.createRuleSession("rules", properties,          RuleRuntime.STATEFUL_SESSION_TYPE);          session.addObject(new Integer(1));          session.addObject("A string");          session.executeRules();          List results = session.getObjects();          session.release();
 
集成JSR-94产品实现        支持JSR 94规范的产品实现既有收费的商业产品,也有免费的开源项目。目前最为成熟,功能最强大的商业产品是ILOG公司的JRules,该公司也是JSR 94规范的积极推动者之一。支持JSR 94规范的开源项目目前很少,只有Drools和JLisa项目。值得注意的是,Jess不是开源项目,它可以免费用于学术研究,但用于商业用途则要收费。
JSR-94的产品实现         Java规则引擎商业产品有:            l. ILOG公司的JRules           2. BlazeSoft公司的Blaze           3. Rules4J           4. Java Expert System Shell (JESS)         开源项目的实现包括:           l. Drools项目
         2. JLisa项目          3. OFBiz Rule Engine(不支持JSR 94)          4. Mandarax(目前不支持JSR 94)
使用Spring集成        集成Java规则引擎的目标是,使用标准的Java规则引擎API封装不同的实现,屏蔽不同的产品实现细节。这样做的好处是,当替换不同的规则引擎产品时,可以不必修改应用代码。
封装JSR-94实现
       RuleEngineFacade类封装Java规则引擎,使用ruleServiceProviderUrl和ruleServiceProviderImpl两个参数,屏蔽了不同产品的配置。代码如下:

       public class RuleEngineFacade {
private RuleAdministrator ruleAdministrator;
private RuleServiceProvider ruleServiceProvider;
private LocalRuleExecutionSetProvider ruleSetProvider;
private RuleRuntime ruleRuntime;
// configuration parameters
private String ruleServiceProviderUrl;
private Class ruleServiceProviderImpl; public void setRuleServiceProviderUrl(String url) {
this.ruleServiceProviderUrl = url;
}
public void setRuleServiceProviderImpl(Class impl) {
this.ruleServiceProviderImpl = impl;
}
public void init() throws Exception {
RuleServiceProviderManager.registerRuleServiceProvider(
ruleServiceProviderUrl, ruleServiceProviderImpl);
ruleServiceProvider = RuleServiceProviderManager.getRuleServiceProvider(ruleServiceProviderUrl);
ruleAdministrator = ruleServiceProvider.getRuleAdministrator();
ruleSetProvider = ruleAdministrator.getLocalRuleExecutionSetProvider(null);
}
public void addRuleExecutionSet(String bindUri,InputStream resourceAsStream)
throws Exception {
Reader ruleReader = new InputStreamReader(resourceAsStream);
RuleExecutionSet ruleExecutionSet =
ruleSetProvider.createRuleExecutionSet(ruleReader, null);
ruleAdministrator.registerRuleExecutionSet(bindUri,ruleExecutionSet,null);
}
public StatelessRuleSession getStatelessRuleSession(String key)
throws Exception {
ruleRuntime = ruleServiceProvider.getRuleRuntime();
return (StatelessRuleSession) ruleRuntime.createRuleSession(key, null, RuleRuntime.STATELESS_SESSION_TYPE);
}
public StatefulRuleSession getStatefulRuleSession(String key)
throws Exception {
ruleRuntime = ruleServiceProvider.getRuleRuntime();
return (StatefulRuleSession) ruleRuntime.createRuleSession(
key, null, RuleRuntime.STATEFUL_SESSION_TYPE);
}
public RuleServiceProvider getRuleServiceProvider() {
return this.ruleServiceProvider;
}
}
封装规则 Rule类封装了具体的业务规则,它的输入参数ruleName是定义规则的配置文件名,并依赖于RuleEngineFacade组件。代码如下:

public class Rule {
private String ruleName;
private RuleEngineFacade engineFacade; public void init() throws Exception {
InputStream is = Rule.class.getResourceAsStream(ruleName);
engineFacade.addRuleExecutionSet(ruleName, is);
is.close();
} public void setRuleName(String name) {
this.ruleName = name;
} public void setEngineFacade(RuleEngineFacade engine) {
this.engineFacade = engine;
} public StatelessRuleSession getStatelessRuleSession()
throws Exception {
return engineFacade.getStatelessRuleSession(ruleName);
} public StatefulRuleSession getStatefuleRuleSession()
throws Exception {
return engineFacade.getStatefulRuleSession(ruleName);
}
}
组装规则组件 组装规则的配置文件如下:

<bean id="ruleEngine" class="spring.RuleEngineFacade" init-method="init" singleton="false">
<property name="ruleServiceProviderUrl">
<value>http://drools.org/</value>
</property>
<property name="ruleServiceProviderImpl">
<value>org.drools.jsr94.rules.RuleServiceProviderImpl</value>
</property>
</bean>
<bean id="fibonacci" class="spring.Rule" init-method="init">
<property name="ruleName">
<value>/test/fibonacci.drl</value>
</property>
<property name="engineFacade">
<ref local="ruleEngine"/>
</property>
</bean>
测试用例 最后,我们编写测试用例,代码如下:

public class JSRTest extends TestCase {
ApplicationContext ctx = null;
protected void setUp() throws Exception {
super.setUp();
ctx = new FileSystemXmlApplicationContext("testrule.xml");
}
public void testGetRuleSession() throws Exception {
Rule rule = (Rule)ctx.getBean("fibonacci");
assertNotNull(rule.getStatefuleRuleSession());
assertNotNull(rule.getStatelessRuleSession());
}
public void testStatelessRule() throws Exception {
Rule rule = (Rule)ctx.getBean("fibonacci");
Fibonacci fibonacci = new Fibonacci(50);
List list = new ArrayList();
list.add(fibonacci);
StatelessRuleSession session = rule.getStatelessRuleSession();
session.executeRules(list);
session.release();
}
public void testStatefulRule() throws Exception {
Rule rule = (Rule)ctx.getBean("fibonacci");
Fibonacci fibonacci = new Fibonacci(50);
StatefulRuleSession session = rule.getStatefuleRuleSession();
session.addObject(fibonacci);
session.executeRules();
session.release();
}
}
 
运行测试用例,出现绿条,测试通过。
规则定义语言之间的变换        因为JSR-94规范并没有强制统一规则定义的语法,因此,当需要将应用移植到其他的Java规则引擎实现时,可能需要变换规则定义,如将Drools私有的DRL规则语言转换成标准的ruleML,Jess规则语言转换成ruleML等。这个工作一般由XSLT转换器来完成。
 
 
 

Java规则引擎及JSR-94[转]的更多相关文章

  1. JAVA规则引擎JSR-94笔札

    JAVA规则引擎JSR-94笔札 JSR-94 是由JCP(Java Community Process)组织所制定的java规则引擎API的java请求规范.它主要定义了规则引擎在java运行时的一 ...

  2. [Drools]JAVA规则引擎 -- Drools- 转http://blog.csdn.net/quzishen/article/details/6163012

    [Drools]JAVA规则引擎 -- Drools 标签: java引擎exceptiongetterstringsetter 2011-01-25 14:33 113340人阅读 评论(35) 收 ...

  3. 【java规则引擎】之规则引擎解释

    转载:http://www.open-open.com/lib/view/open1417528754230.html 现实生活中,规则无处不在.法律.法规和各种制度均是:对于企业级应用来说,在IT技 ...

  4. Java规则引擎 Easy Rules

    1.  Easy Rules 概述 Easy Rules是一个Java规则引擎,灵感来自一篇名为<Should I use a Rules Engine?>的文章 规则引擎就是提供一种可选 ...

  5. JAVA规则引擎 -- Drools

    Drools是一个基于java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...

  6. [Drools]JAVA规则引擎 -- Drools 2

    上一篇文章 http://blog.csdn.net/quzishen/archive/2011/01/25/6163012.aspx 描述了一些常用的drools的语法标签和一个模拟实例即发送积分的 ...

  7. [Drools]JAVA规则引擎 -- Drools

    Drools是一个基于Java的规则引擎,开源的,可以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效. 本文所使用的de ...

  8. java 规则引擎资料汇集

    1. ibm的developworks中较早的一篇关于规则引擎的文章 https://www.ibm.com/developerworks/cn/java/j-java-rules/ 2. 一篇硕士论 ...

  9. 【java规则引擎】一个基于drools规则引擎实现的数学计算例子

    最近在研究JBPM工作流引擎,发现JBPM是基于Drools的,官方文档查看得知Drools是一款规则引擎.兴趣之下,仔细了解了下 Drools,Drools作为JBoss出品的一款开源推理和规则引擎 ...

随机推荐

  1. iOS 解决上传100张图片内存奔溃问题

    最近项目需求,从相册中提取100张图片,然后上传到服务器.前提是图片不能压缩.因为要将图片信息采集出来制作出3D模型.所以必须是高清图片. 先看下代码 [NetWorking uploadWithUr ...

  2. ubuntu安装依赖:0.8.1-1ubuntu4.4 正要被安装以及vm nested解决方法

    刚才在ubuntu10.04虚拟机上安装kvm,提示0.8.1-1ubuntu4.4 正要被安装,查了一下,有一种解决方法: 进入“系统->系统管理->更新管理器->设置”,在弹出的 ...

  3. Vim:基础

    Normal模式 即是command “vim test.txt” 时进入的界面. 常用command: :help<Enter>   查看命令. :wq<Enter>     ...

  4. 每天一个linux命令:【转载】cat命令

    cat命令的用途是连接文件或标准输入并打印.这个命令常用来显示文件内容,或者将几个文件连接起来显示,或者从标准输入读取内容并显示,它常与重定向符号配合使用. 1.命令格式: cat [选项] [文件] ...

  5. 《DSP using MATLAB》示例Example 6.12

    上代码: % x = -8:7 y = TwosComplement(x, 4) y = dec2bin(y, 4); disp(sprintf('%s', [y'; char(ones(1, 16) ...

  6. 解决js代码中加入alert()就成功执行,不加就不对的问题!

    问题: jquery中的$(document).ready(function(){})中调用两个方法(1)利用ajax请求去后台查图书类别的方法(2)当页面上利用图书类别去查询图书返回页面,让图书类别 ...

  7. 第一次Sprint团队贡献分

    201406114105       董婷婷           21 201406114157       容杰龙           22 201406114343       卓炜杰       ...

  8. oracle之 v$sql_monitor 监视正在运行的SQL语句的统计信息

    11g中引入了新的动态性能视图V$SQL_MONITOR,该视图用以显示Oracle监视的SQL语句信息.SQL监视会对那些并行执行或者消耗5秒以上cpu时间或I/O时间的SQL语句自动启动,同时在V ...

  9. MyEclipse中将普通Java项目convert(转化)为Maven项目

    在MyEclipse10中将Maven项目转成普通Java项目后,想将Java项目转成Maven项目,结果一下子傻眼了.根本就没有攻略中提到的config标签.仔细一看,喵咪的,人家用的是Eclips ...

  10. 完美版js金钱正则表达式校验

    <!doctype html> <html lang="en">  <head>   <meta charset="UTF-8& ...