1、规则引擎
一个规则引擎可以被简单的视为一个IF/THEN表达式的解释机制。向规则引擎输入一个规则序列和一些数据对象,它就会输出被修改的输入数据对象或者新的一些对象,以及产生一些副作用,比如发电子邮件之类的操作。
即使遵循JSR94的不同的规则引擎,其也是存在差别的。JSR94基本上只是规范了客户端调用规则引擎的接口,对规则引擎实现相关技术没有进行规范。如下实现技术不是规范中的内容:
*规则以及规则执行序列(rule execution sets)的二进制表示
*规则以及规则执行序列的文件格式结构
*规则以及规则执行序列的解释语义
*规则以及规则执行序列的转换机制
典型的规则引擎具有如下特性:
*提供具体商业和应用逻辑基础上的声明式编程
*包含一种文件格式或者工具,来定义规则和规则执行序列
*根据输入的对象来生产输出对象。输入对象可以看作是事实,其表示应用域的某种状态;而输出对象可以看作是结论或者推论
*规则引擎可以直接执行活动,对应用域、输入对象、执行周期、规则或者引擎本身产生影响
*规则引擎可以只产生输出对象,并将其交给调用者去处理。
最常见的规则引擎类型是Forward-chaining规则引擎,其特点是一个规则的执行结论可能是其他规则触发的条件,这样一直下去。Forward -chaining规则引擎适合于处理给出一些简单的事实而推论出更高层次的结果。JSR94标准主要是针对Forward-chaining规则引擎 的。
2、规则
一个规则由两部分组成:一个条件和一个活动。JSR94没有规范规则的结构,各种不同的规则引擎差别很大。
3、规则执行序列(rule execution set)
一个规则执行序列是一些规则的集合。JSR94没有规范其结构
4、规则会话(rule session)
客户端与规则引擎的一个运行时连接。一个规则会话与唯一一个规则执行序列相关联。规则会话必须显示的释放。
5、有状态的规则会话
输入对象可逐渐增加到会话中,结果对象可以重复查询
6、无状态的规则会话
高性能,API简单。输入为对象列表(List)
**介绍**
规则引擎处理周期包括:规则解析、增加对象到引擎、命中规则、从引擎获取结果。规则引擎的主要输入是被称为规则执行序列的规则集合。JSR94中没有对规则描述语言以及规则引擎执行周期进行约定。JSR94中只定义了规则引擎的操作接口。
**构架**
规则引擎的接口和类定义在javax.rules和javax.rules.admin包中。其中javax.rules包中的接口和类提供给规则引擎的客户端使用,提供为注册的规则执行序列获取一个规则会话和与会话交互的功能。管理API提供从URI,InputStream,XML,Reader等外部资源装入一个规则执行序列;同时也提供注册规则执行序列和撤销注册的功能。只有注册的序列是可以被客户端访问的。
运行时API:
也就是在javax.rules包中的类和接口。运行时API主要包括以下功能:
-通过RuleServiceProviderManager类获取一个实现RuleServiceProvider接口的规则引擎实例
-通过RuleServiceProvider获取一个RuleRuntime接口实例
-通过RuleRuntime创建一个RuleSession会话
-获取被注册URI的列表(java.util.List)
-通过RuleExecutionSetMetadata接口为会话(RuleSession)获取原数据
-通过一个ObjectFilter接口来过滤执行RuleExecutionSet的结果
-通过Handle实例访问放置于StatefulRuleSession中的对象。
RuleServiceProviderManager
RuleServiceProviderManager用于从发行商发布的规则引擎产品中获取一个RuleServiceProvider接口的实现。这一点很类似于JDBC中DriverManager和Driver的关系。使用类似JDBC的URL,客户端可以通过RuleServiceProviderManager类获取一个实现了RuleServiceProvider接口的类,我们并不需要知道这个类具体是什么。
例如:
Class.forName(“org.jcp.jsr94.ri.RuleServiceProvider”);
RuleServiceProvider rsp = RuleServiceProviderManager
.getRuleServiceProvider(“org.jcp.jsr94.ri.RuleServiceProvider”);
例1:演示如何使用RuleAdministrator从外部资源创建一个RuleExecutionSet,如何为RuleExecutionSet创建RuleSession,以及如何使用RuleSession处理输入对象得到输出对象。
//装入RuleServiceProvider
Class.forName(“org.jcp.jsr94.ri.RuleServiceProvider”);
RuleServiceProvider serviceProvider = RuleServiceProviderManager
.getRuleServiceProvider(RULE_SERVICE_PROVIDER);
//创建一个无状态的RuleSession
RuleRuntime ruleRuntime = serviceProvider.getRuleRuntime();
StatelessRuleSession srs = (StatelessRuleSession) ruleRuntime
.createRuleSession(bindUri, null, RuleRuntime.STATELESS_SESSION_TYPE);
//执行所有的规则
List inputList = new LinkedList();
inputList.add(new String(“Hi”));
inputList.add(new String(“hoo”));
inputList.add(new Integer(5));
List resultList = srs.executeRules(inputList);
//释放会话资源
srs.release();
例2:规则管理,演示了如何从外部资源创建RuleExecutionSet,然后注册。
String RULE_SERVICE_PROVIDER = “org.jcp.jsr94.jess”;
// 装入JSR94参考实现的规则服务提供者(RuleServiceProvider)
Class.forName(“org.jcp.jsr94.jess.RuleServiceProviderImpl”);
// 通过RuleServiceProviderManager获取RuleServiceProvider
RuleServiceProvider serviceProvider = RuleServiceProviderManager.getRuleServiceProvider(
RULE_SERVICE_PROVIDER);
//获取RuleAdministrator
RuleAdministrator ruleAdministrator = serviceProvider.getRuleAdministrator();
//获取一个输入流,它包含着规则定义
InputStream inStream = getResourceAsStream(“input_rules.xml”);
//解析流中的规则定义
RuleExecutionSet res1 = ruleAdministrator.getLocalRuleExecutionSetProvider(null)
.createRuleExecutionSet(inStream,null);
inStream.close();
//注册这个RuleExecutionSet
String uri = res1.getName();
ruleAdministrator.registerRuleExecutionSet(uri, res1 , null);
例3:无状态的规则会话,演示从上面示例代码中注册的RuleExecutionSet中获取StatelessRuleSession实例,并执行规则。
String RULE_SERVICE_PROVIDER = “org.jcp.jsr94.jess”;
// 装入JSR94参考实现的规则服务提供者(RuleServiceProvider)
Class.forName(“org.jcp.jsr94.jess.RuleServiceProviderImpl”);
// 通过RuleServiceProviderManager获取RuleServiceProvider
RuleServiceProvider serviceProvider = RuleServiceProviderManager.getRuleServiceProvider(
RULE_SERVICE_PROVIDER);
//获取RuleRuntime并调用规则引擎
RuleRuntime ruleRuntime = serviceProvider.getRuleRuntime();
//创建一个无状态会话
StatelessRuleSession statelessRuleSession = (StatelessRuleSession) ruleRuntime
.createRuleSession(uri, new HashMap(), RuleRuntime.STATELESS_SESSION_TYPE);
//调用executeRules执行规则
Customer inputCustomer = new Customer(“test”);
inputCustomer.setCreditLimit(5000);
List input = new ArrayList();
Input.add(inputCustomer);
//执行规则,不带有过滤器
List results = statelessRuleSession.executeRules(input);
//释放资源
statelessRuleSession.release();
例4:有状态规则会话,演示从上面示例代码中注册的RuleExecutionSet中获取StatefulRuleSession实例,然后加入输入对象,并使用Handle访问对象,最后提取结果对象。
String RULE_SERVICE_PROVIDER = “org.jcp.jsr94.jess”;
// 装入JSR94参考实现的规则服务提供者(RuleServiceProvider)
Class.forName(“org.jcp.jsr94.jess.RuleServiceProviderImpl”);
// 通过RuleServiceProviderManager获取RuleServiceProvider
RuleServiceProvider serviceProvider = RuleServiceProviderManager.getRuleServiceProvider(
RULE_SERVICE_PROVIDER);
//获取RuleRuntime并调用规则引擎
RuleRuntime ruleRuntime = serviceProvider.getRuleRuntime();
//创建一个有状态会话
StatefulRuleSession statefulRuleSession = (StatefulRuleSession) ruleRuntime
.createRuleSession(uri, new HashMap(), RuleRuntime.STATEFULL_SESSION_TYPE);
//增加输入对象
Invoice inputInvoice = new Invoice(“Invoice”);
inputInvoice.setAmount(1750);
statefulRuleSession.addObject(inputInvoice);
//执行规则
statefulRuleSession.executeRules();
//提取结果
results = statefulRuleSession.getObjects();
//增加其他输入对象
Invoice inputInvoice2 = new Invoice(“Invoice 2”);
inputInvoice2.setAmount(4000);
//执行规则
statefulRuleSession.executeRules();
//提取结果
results = statefulRuleSession.getObjects();
//释放资源
statefulRuleSession.release();