源码地址:https://svn.codehaus.org/activiti
Drools在activiti中作为一个任务节点存在
<bussinessRuleTask/>
在activiti源码org.activiti.engine.impl.rules包下有这样3个类,它们会在流程实例执行到此节点时,流程引擎调用BusinessRuleTaskActivityBehavior的execut方法开始执行活动行为后,BusinessRuleTaskActivityBehavior需要借助这3个类来帮助最终触发规则,完成此任务节点。
(1)RulesAgendaFilter
它简单的实现了org.drools.runtime.rule.AgendaFilter接口
(根据流程定义文件所配置的activiti:rules进行判断,要准备触发规则文件中哪些rule)
(2)RulesDeployer
规则部署类
它只有一个deploy方法
它会从activiti的部署归档文件中找出后缀为drl的规则文件,用drools的
KnowledgeBuilder类去编译这些规则文件
knowledgeBuilder.add(droolsResource, ResourceType.DRL)
并创建一个KnowledgeBase的实例并且放入缓存
注:规则文件不一定只能是.drl
(3)RulesHelper
工具类,根据部署文件的id从对应的部署文件缓存中拿出KnowledgeBase实例
当流程实例开始后,到达bussinessRuleTask节点后,BusinessRuleTaskActivityBehavior的execute方法会被调用,开始节点的行为.
BusinessRuleTaskActivityBehavior execute的源码片段如下:
//根据部署文件ID获得对应knowledgeBase KnowledgeBase knowledgeBase = RulesHelper.findKnowledgeBaseByDeploymentId(deploymentId); //生成一个StarefulKnowledgeSession实例 //它可以对fact对象(插入到WorkingMemory后的pojo)进行操作 //StatefulKnowledgeSession是WorkingMemory的子类 StatefulKnowledgeSession ksession = knowledgeBase.newStatefulKnowledgeSession();
要插入的pojo对应activiti:ruleVariablesInput,
触发哪几个规则对应activiti:rules,
//对应activiti:ruleVariablesInput if (variablesInputExpressions != null) { Iterator<Expression> itVariable = variablesInputExpressions.iterator(); while (itVariable.hasNext()) { Expression variable = itVariable.next(); //pojo插入到workMemory,成为fact对象,返回一个pojo的引用 ksession.insert(variable.getValue(execution)); } } //根据过滤或留下(根据配置否exclude)规则文 //件。。。略 filter.setAccept(!exclude); //触发规则 ksession.fireAllRules(filter); 规则的输出将作为流程变量被保存在activiti:resultVariable所定义的值中