You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drools7.0.0无状态KieSession规则执行顺序全量打印可行性咨询

在Drools 7.0.0的StatelessKieSession中,无法直接获取未满足条件的规则的评估顺序——因为引擎通过Rete网络优化了匹配过程,仅会处理那些条件匹配成功、进入议程的规则。但如果你的需求是记录实际触发执行的规则顺序,或是验证规则执行顺序的不确定性,完全可以通过以下方式实现:

方法1:用自定义监听器记录触发的规则顺序

通过实现AgendaEventListener,可以监听规则触发的前后事件,从而记录执行顺序:

  1. 编写自定义监听器类:
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;
    }
}
  1. 在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 11:35:13