Drools7.0.0无状态KieSession规则执行顺序全量打印可行性咨询
在Drools 7.0.0的StatelessKieSession中,无法直接获取未满足条件的规则的评估顺序——因为引擎通过Rete网络优化了匹配过程,仅会处理那些条件匹配成功、进入议程的规则。但如果你的需求是记录实际触发执行的规则顺序,或是验证规则执行顺序的不确定性,完全可以通过以下方式实现:
方法1:用自定义监听器记录触发的规则顺序
通过实现AgendaEventListener,可以监听规则触发的前后事件,从而记录执行顺序:
- 编写自定义监听器类:
import org.kie.api.event.rule.AfterMatchFiredEvent; import org.kie.api.event.rule.DefaultAgendaEventListener; import java.util.ArrayList; import java.util.List; public class RuleTraceListener extends DefaultAgendaEventListener { private final List<String> firedRules = new ArrayList<>(); @Override public void afterMatchFired(AfterMatchFiredEvent event) { String ruleName = event.getMatch().getRule().getName(); firedRules.add(ruleName); System.out.printf("触发规则:%s%n", ruleName); } public List<String> getFiredRules() { return firedRules; } }
- 在StatelessKieSession中注册监听器并执行:
KieServices kieServices = KieServices.Factory.get(); KieContainer kieContainer = kieServices.getKieClasspathContainer(); StatelessKieSession session = kieContainer.newStatelessKieSession(); RuleTraceListener traceListener = new RuleTraceListener(); session.addEventListener(traceListener); // 传入payload执行规则 session.execute(yourPayload); // 输出最终执行顺序 List<String> executionOrder = traceListener.getFiredRules(); System.out.printf("规则执行顺序:%s%n", String.join("→", executionOrder));
方法2:验证规则执行顺序的不确定性
如果要证明无优先级规则的执行顺序是任意的,可以:
- 确保所有规则未设置
salience属性(默认优先级为0) - 多次运行相同的payload,观察触发顺序是否变化;或是调整事实插入的顺序,看匹配顺序是否改变
关于未匹配规则的记录说明
如果必须追踪所有规则的评估轨迹,只能通过修改规则逻辑模拟:给每个规则添加eval(true)的前置条件,结合全局变量记录规则被评估的情况,但这种方式会降低引擎性能,且仅能记录匹配成功的规则(因为未匹配的规则不会进入then块执行记录逻辑)。示例如下:
修改后的规则:
global java.util.List<String> evaluatedRules; rule "My First Rule" when eval(true) $payload: Payload() // 原规则条件 $payload.meetsFirstCondition() not Routing() then evaluatedRules.add("My First Rule"); insert(new Routing("First")); end rule "My Second Rule" when eval(true) $payload: Payload() // 原规则条件 $payload.meetsSecondCondition() not Routing() then evaluatedRules.add("My Second Rule"); insert(new Routing("Second")); end
代码中传入全局变量:
List<String> evaluatedRules = new ArrayList<>(); session.setGlobal("evaluatedRules", evaluatedRules); session.execute(yourPayload); System.out.printf("已评估的匹配规则顺序:%s%n", String.join("→", evaluatedRules));
内容的提问来源于stack exchange,提问作者Betty Ong
相关产品推荐
相关产品推荐

