DROOLS 8:如何通过RuleUnit获取已触发规则
在Drools 8中通过RuleUnit记录已触发规则的方法
是的,你可以通过RuleUnit实现已触发规则的记录,以下是几种可行的实用方案:
方案1:利用RuleUnit的@OnMatch回调(推荐)
RuleUnit原生提供了@OnMatch注解,可直接在RuleUnit类中定义规则触发后的回调逻辑,无需依赖KieSession监听器。
示例代码:
public class MyRuleUnit implements RuleUnitData { // 存储已触发的规则名称 private List<String> firedRules = new ArrayList<>(); // 规则触发时自动调用的回调方法 @OnMatch public void onRuleFired(Match match) { String ruleName = match.getRule().getName(); firedRules.add(ruleName); // 这里可添加自定义日志逻辑,比如写入文件或控制台打印 System.out.println("已触发规则:" + ruleName); } // 获取已触发规则列表的方法 public List<String> getFiredRules() { return firedRules; } }
执行RuleUnit后获取记录:
KieServices kieServices = KieServices.Factory.get(); KieContainer kContainer = kieServices.getKieClasspathContainer(); RuleUnitExecutor executor = RuleUnitExecutor.create().bind(kContainer); MyRuleUnit ruleUnit = new MyRuleUnit(); executor.run(ruleUnit); // 获取所有已触发的规则 List<String> firedRules = ruleUnit.getFiredRules();
方案2:在规则逻辑中直接记录
如果需要更细粒度的控制,可在规则的then块中直接向RuleUnit的数据对象添加规则名称:
规则文件(.drl):
package com.example.rules; unit MyRuleUnit; rule "UserValidationRule" when User(age < 18) then // 将当前规则名称存入RuleUnit的记录列表 getRuleUnit().getFiredRules().add("UserValidationRule"); // 业务逻辑 end rule "OrderDiscountRule" when Order(totalAmount > 1000) then getRuleUnit().getFiredRules().add("OrderDiscountRule"); // 业务逻辑 end
对应的RuleUnit类仅需提供存储容器:
public class MyRuleUnit implements RuleUnitData { private List<String> firedRules = new ArrayList<>(); public List<String> getFiredRules() { return firedRules; } }
方案3:结合RuleUnit与KieSession监听器
若你习惯使用beforeMatchFired这类监听器模式,也可从RuleUnitExecutor中获取KieSession并注册监听器:
RuleUnitExecutor executor = RuleUnitExecutor.create().bind(kContainer); KieSession ksession = executor.getKieSession(); List<String> firedRules = new ArrayList<>(); ksession.addEventListener(new DefaultAgendaEventListener() { @Override public void beforeMatchFired(BeforeMatchFiredEvent event) { String ruleName = event.getMatch().getRule().getName(); firedRules.add(ruleName); System.out.println("即将触发规则:" + ruleName); } }); MyRuleUnit ruleUnit = new MyRuleUnit(); executor.run(ruleUnit);
这种方式兼容你熟悉的监听器逻辑,同时可配合RuleUnit的执行流程使用。
内容的提问来源于stack exchange,提问作者Richard
相关产品推荐
相关产品推荐

