本文节选自《疯狂工作流讲义(第2版)》
京东购买地址:https://item.jd.com/12246565.html
工作流Activiti6电子书:http://blog.csdn.net/boxiong86/article/details/78488562
工作流Activiti6教学视频:http://blog.csdn.net/boxiong86/article/details/78608585
Activiti与Drools整合
使用Activiti中的业务规则任务(Business Rule Task)可以执行一个或者多个业务规则,当前Activiti只支持Drools。根据流程任务章节可知,每个流程活动都会有自己的行为,那么Activiti在实例业务规则任务行为的时候,只需要使用Drools的API,就可以实现规则文件的加载、事实实例的插入和规则触发等操作,任务的定义者只需要提供参数、规则和计算结果等信息,就可以在Activiti中调用规则。
业务规则任务详解
在调用规则前,需要告诉规则引擎加载哪些规则文件,而对于Activiti来说,这些文件都会被看作资源(数据被保存在ACT_GE_BYTEARRAY表中),因此在部署流程资源文件时,就需要提供这些规则文件。当执行流到达业务规则任务时,就会执行业务规则任务的行为,Activiti中对应的行为实现类是BusinessRuleTaskActivityBehavior,那么根据本章前面几节中Drools的API可以知道,这个类的实现应该是创建(获取缓存中的)KnowledgeBase实例,然后创建一个StatefulKnowledgeSession实例,插入事实实例,最后调用fireAllRules方法触发规则。BusinessRuleTaskActivityBehavior的实现大致如代码清单14-26所示。
代码清单14-26:
//创建一个KnowledgeBuilder
KnowledgeBuilder kbuilder = KnowledgeBuilderFactory
.newKnowledgeBuilder();
//添加规则资源到KnowledgeBuilder
kbuilder.add(ResourceFactory.newClassPathResource("rule/MyDrools.drl",
FirstTest.class), ResourceType.DRL);
if (kbuilder.hasErrors()) {
System.out.println(kbuilder.getErrors().toString());
System.exit(0);
}
//获取知识包集合
Collection<KnowledgePackage> pkgs = kbuilder
.getKnowledgePackages();
//创建KnowledgeBase实例
KnowledgeBase kbase =kbuilder.newKnowledgeBase();①
//将知识包部署到KnowledgeBase中
kbase.addKnowledgePackages(pkgs);
//使用KnowledgeBase创建StatefulKnowledgeSession
StatefulKnowledgeSession ksession = kbase
.newStatefulKnowledgeSession();
//创建事实
Person p1 = newPerson("person 1", 11);
//插入到Working Memory
ksession.insert(p1);
//匹配规则
ksession.fireAllRules();
//关闭当前session的资源
ksession.dispose();
从代码清单14-26的①开始,将会是BusinessRuleTaskActivityBehavior所做的工作,Activiti的实现与代码清单14-26存在差异,KnowledgeBase实例的创建将由Activiti的其他类完成,包括KnowledgeBuilder的创建、编译信息输出等工作,BusinessRuleTaskActivityBehavior的实现中,得到KnowledgeBase后,会创建一个StatefulKnowledgeSession,然后根据任务节点的配置,解析为事实实例,调用StatefulKnowledgeSession的insert方法插入到Working Memory中,最后会触发全部的规则并关闭资源。需要注意的是,触发规则时,会读取任务所配置的规则来添加一个规则拦截器,调用StatefulKnowledgeSession的fireAllRules(AgendaFilter filte)方法来触发规则,如果在任务中没有配置使用(或者不使用)的规则,那么将调用无参数的fireAllRules方法。在接下来的两个小节,将以一个销售流程为基础,在Activiti中调用规则。
制定销售单优惠规则
假设当前有一个销售流程,销售人员在录入销售商品后,系统需要对录入的商品进行规则处理,例如在单笔消费100元以上打九折、200元以上打八折等优惠策略,都可以在规则文件中定义,然后通过业务规则任务的调用,最后通过一个ServiceTask来输出计算后的结果。在设定销售流程前,可以先设计相应的销售对象。代码清单