如何在Drools项目中指定执行特定规则而非全部规则?
在Drools中仅执行特定规则的实现方法
当Drools规则文件中包含多条规则时,若需绕过kieSession.fireAllRules()方法,仅执行指定的1条或多条规则,可通过以下方案实现:
原有DRL规则文件示例
package com.baeldung.drools.rules; import com.baeldung.drools.model.Applicant; global com.baeldung.drools.model.SuggestedRole suggestedRole; dialect "mvel" rule "Suggest Manager Role" when Applicant(experienceInYears > 10) Applicant(currentSalary > 1000000 && currentSalary <= 2500000) then suggestedRole.setRole("Manager"); end // 假设此处还有其他规则,例如"Suggest Senior Engineer Role"等
原有Java调用代码示例
public SuggestedRole suggestARoleForApplicant( Applicant applicant, SuggestedRole suggestedRole){ KieSession kieSession = kieContainer.newKieSession(); kieSession.insert(applicant); kieSession.setGlobal("suggestedRole", suggestedRole); kieSession.fireAllRules(); // 不想执行所有规则,只想执行特定规则 // ... return suggestedRole; }
实现仅执行特定规则的步骤(不使用fireAllRules())
核心思路是通过Drools的Agenda API手动定位并执行目标规则的激活实例:
步骤1:获取会话的Agenda对象
插入业务事实、设置全局变量后,调用kieSession.getAgenda()获取Agenda实例,它负责管理所有已满足触发条件的规则激活。
步骤2:匹配目标规则的激活实例
遍历Agenda中的所有激活实例,通过规则名称精准匹配需要执行的目标规则。
步骤3:执行指定的激活实例
对匹配到的目标Activation调用fire()方法,即可单独执行该规则。
完整代码实现
public SuggestedRole suggestARoleForApplicant( Applicant applicant, SuggestedRole suggestedRole){ KieSession kieSession = kieContainer.newKieSession(); try { kieSession.insert(applicant); kieSession.setGlobal("suggestedRole", suggestedRole); // 获取Agenda实例 Agenda agenda = kieSession.getAgenda(); // 遍历激活实例,执行指定规则 for (Activation activation : agenda.getActivations()) { Rule rule = activation.getRule(); // 可添加多个规则名称,实现执行多条特定规则 if ("Suggest Manager Role".equals(rule.getName())) { activation.fire(); // 若仅需执行一条,匹配后可break跳出循环 // break; } } } finally { kieSession.dispose(); // 必须关闭会话释放资源 } return suggestedRole; }
补充:官方推荐的高效实现(兼容fireAllRules())
若对“不使用fireAllRules()”的要求并非绝对严格,fireAllRules()支持传入AgendaFilter参数,这种方式更简洁高效:
public SuggestedRole suggestARoleForApplicant( Applicant applicant, SuggestedRole suggestedRole){ KieSession kieSession = kieContainer.newKieSession(); try { kieSession.insert(applicant); kieSession.setGlobal("suggestedRole", suggestedRole); // 自定义过滤器,仅允许指定规则执行 AgendaFilter ruleFilter = activation -> { String ruleName = activation.getRule().getName(); return ruleName.equals("Suggest Manager Role") || ruleName.equals("Suggest Senior Engineer Role"); }; // 仅执行符合过滤条件的规则 kieSession.fireAllRules(ruleFilter); } finally { kieSession.dispose(); } return suggestedRole; }
内容的提问来源于stack exchange,提问作者BRUNO
相关产品推荐
相关产品推荐

