Drools 规则流的使用介绍
蒙麒
2023-12-01
由于工作中长时间使用drools进行开发规则引擎,没有及时的将该规则引擎进行分享出来,以下是drools流的介绍:
Drools(JBoss Rules )具有一个易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。业务分析师或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。
Drools Flow为Drools平台提供了工作流或者(业务)流程能力。一个业务流程或者工作流使用一个流程图表描述了一系列需要执行的步骤的顺序。这使得它更容 易来描述一个各种不同任务的复杂组合。流程在描述基于状态的,长时间运行的过程时特别有用。Drools Flow允许最终用户使用这些流程来指定,执行和监控(一部分)他们的业务逻辑。Drools Flow流程框架可以很容易地嵌入到任何的Java应用中(作为一个简单的Java组件)或者能够以一个服务器环境的模式独立运行。
Drools 流是一个工作流或流程的引擎,允许流程和规则的高级集成。流程或工作流使用流程图描述了需要执行的一系列步骤的顺序。如下图所示: 执行 tested 或 test 后在执行 test2,rule 完成结束。
[img]http://dl2.iteye.com/upload/attachment/0101/4518/0397efc4-eabe-3f4e-9348-0983f4187bca.bmp[/img]
第一步:首先创建一个drools project 项目工作;
第二步:创建一个 *.drl 文件,和一个 *.rf 文件;对于drl 文件时存放规则库的,rf文件定义的规则流的流程;
[color=red]*.drl 文件内容:[/color]
package com.wm
import com.sample.RuleFlow;
#list any import classes here.
#declare any global variables here
#说明:如果在规则流中使用组建Gateway为split ,
#在规则中更新workingmemory中不会被其他规则使用更新后的值
rule "First"
lock-on-active true
ruleflow-group 'tested'
when
$rf:RuleFlow(userName=="wangm");
# eval($rf.getUserName()=="wangm");
then
$rf.setAge(10);
$rf.setUserName("wangmm");
update($rf);
System.out.println($rf.getUserName());
end
rule "Second"
no-loop true
#lock-on-active true
ruleflow-group 'test'
when
$rf:RuleFlow(userName=="wangm" && age < 18);
then
$rf.setSource(58);
update($rf);
System.out.println("未成年");
end
rule "Third"
no-loop true
#lock-on-active true
ruleflow-group 'test'
when
$rf:RuleFlow(userName=="wangmm" && age >= 18);
then
$rf.setSource(100);
update($rf);
System.out.println("已成年");
end
rule "Third2"
no-loop true
ruleflow-group 'test2'
when
$rf:RuleFlow(userName=="wangmm" && source < 60);
then
System.out.println($rf.getUserName()+"的年龄为"+$rf.getAge()+" 成绩为"+$rf.getSource()+" 规则 (Third2)");
$rf.setSource($rf.getSource()+10);
update($rf);
end
rule "Third3"
no-loop true
# lock-on-active true
ruleflow-group 'test2'
when
$rf:RuleFlow(userName=="wangmm" && source >= 60);
then
System.out.println($rf.getUserName()+"的年龄为"+$rf.getAge()+" 成绩为"+$rf.getSource()+" 规则 (Third3)");
$rf.setSource($rf.getSource()+1);
update($rf);
end
rule "Third4"
no-loop true
# lock-on-active true
ruleflow-group 'test3'
when
$rf:RuleFlow();
eval(true);
then
System.out.println($rf.getUserName()+"的年龄为"+$rf.getAge()+" 成绩为"+$rf.getSource()+" 规则(Third4)");
end
[color=red]*.rf 文件源码:[/color]
<?xml version="1.0" encoding="UTF-8"?>
<process xmlns="http://drools.org/drools-5.0/process"
xmlns:xs="http://www.w3.org/2001/XMLSchema-instance"
xs:schemaLocation="http://drools.org/drools-5.0/process drools-processes-5.0.xsd"
type="RuleFlow" name="flow2" id="1" package-name="com.wm" version="" >
<header>
</header>
<nodes>
<start id="1" name="Start" x="7" y="71" width="48" height="48" />
<ruleSet id="2" name="tested" x="177" y="16" width="80" height="48" ruleFlowGroup="tested" />
<end id="7" name="End" x="482" y="96" width="48" height="48" />
<ruleSet id="9" name="test" x="177" y="96" width="80" height="48" ruleFlowGroup="test" />
<ruleSet id="10" name="test2" x="328" y="178" width="80" height="48" ruleFlowGroup="test2" />
<split id="11" name="Gateway" x="88" y="95" width="49" height="49" type="3" >
<constraints>
<constraint toNodeId="9" toType="DROOLS_DEFAULT" name="toTest" priority="1" type="rule" dialect="java" >eval(true)</constraint>
<constraint toNodeId="2" toType="DROOLS_DEFAULT" name="toTested" priority="1" type="rule" dialect="java" >eval(true)</constraint>
</constraints>
</split>
<join id="12" name="dd" x="289" y="96" width="49" height="49" type="1" />
<ruleSet id="13" name="Rule" x="370" y="96" width="80" height="48" ruleFlowGroup="test3" />
</nodes>
<connections>
<connection from="11" to="2" />
<connection from="13" to="7" />
<connection from="11" to="9" />
<connection from="12" to="10" />
<connection from="1" to="11" />
<connection from="2" to="12" />
<connection from="9" to="12" />
<connection from="10" to="13" />
</connections>
</process>
第三步:创建一个测试类:代码如下
package com.sample;
import org.drools.KnowledgeBase;
import org.drools.KnowledgeBaseFactory;
import org.drools.builder.KnowledgeBuilder;
import org.drools.builder.KnowledgeBuilderError;
import org.drools.builder.KnowledgeBuilderErrors;
import org.drools.builder.KnowledgeBuilderFactory;
import org.drools.builder.ResourceType;
import org.drools.io.ResourceFactory;
import org.drools.logger.KnowledgeRuntimeLogger;
import org.drools.logger.KnowledgeRuntimeLoggerFactory;
import org.drools.runtime.StatefulKnowledgeSession;
/**
*
* Created on 2014-7-30
规则流测试类
*/
public class RuleFlowTest
{
public static void main(String[] args)
{
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
// kbuilder.add(ResourceFactory.newClassPathResource("test3.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("ruleFlow.drl"), ResourceType.DRL);
kbuilder.add(ResourceFactory.newClassPathResource("ruleflowed.rf"), ResourceType.DRF);
// kbuilder.add(ResourceFactory.newClassPathResource("dd.bpmn"), ResourceType.BPMN2);
KnowledgeBuilderErrors errors = kbuilder.getErrors();
if (errors.size() > 0) {
for (KnowledgeBuilderError error: errors) {
System.err.println(error);
}
throw new IllegalArgumentException("Could not parse knowledge.");
}
KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
KnowledgeRuntimeLogger logger = KnowledgeRuntimeLoggerFactory.newFileLogger(ksession, "ruleflow");
RuleFlow rf = new RuleFlow();
rf.setUserName("wangm");
rf.setSex("男");
rf.setAge(18);
rf.setSource(88);
ksession.insert(rf);
ksession.startProcess("1");
ksession.fireAllRules();
ksession.dispose();
}
}
通过以上也就是一个简单入门的规则流实例,对于源代码可以从附件中下载。
其他可以参考:
http://www.cnblogs.com/skyme/archive/2011/11/14/2245558.html