在Drools 8的规则引擎体系中,Agenda是负责管理所有可触发规则队列的核心组件,当规则的条件被满足时,对应的规则实例会被加入到Agenda中等待执行。很多时候我们需要获取Agenda中已有的规则信息,比如统计即将执行的规则数量、查看规则的名称和元数据,或者根据业务需求过滤掉部分不需要执行的规则,这就需要掌握从Agenda中提取规则信息的具体方法。

Drools 8中Agenda的基础概念
Agenda是Drools引擎中规则调度的核心模块,所有满足触发条件的规则都会被放入Agenda的队列中,引擎会按照规则的优先级、冲突解决策略依次执行队列中的规则。在Drools 8里,我们可以通过KieSession对象获取到对应的Agenda实例,进而操作其中的规则相关内容。
Agenda中的规则以AgendaItem的形式存在,每个AgendaItem对应一个待执行的规则实例,包含了规则的名称、优先级、绑定的事实对象、元数据等核心信息,我们可以通过操作AgendaItem来获取需要的规则数据。
从Agenda获取规则信息的实现步骤
1. 配置KieSession并触发规则
首先需要构建Drools 8的规则项目,配置好Kie容器和KieSession,然后插入事实对象触发规则,让符合条件的规则进入Agenda队列。以下是基础的配置和事实插入代码:
// 获取Kie容器
KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 创建KieSession
KieSession kieSession = kieContainer.newKieSession();
// 定义一个简单的事实对象
public class Order {
private double amount;
public Order(double amount) {
this.amount = amount;
}
public double getAmount() {
return amount;
}
}
// 插入事实对象触发规则
Order order = new Order(500);
kieSession.insert(order);
// 触发规则,此时符合条件的规则会进入Agenda
kieSession.fireAllRules();
2. 使用Agenda过滤器获取规则信息
Drools 8提供了AgendaFilter接口,我们可以在规则触发阶段通过过滤器拦截Agenda中的规则项,从而获取规则的相关信息。实现AgendaFilter的accept方法,就可以在规则即将执行时拿到对应的AgendaItem:
import org.kie.api.runtime.rule.AgendaFilter;
import org.kie.api.runtime.rule.AgendaItem;
// 自定义Agenda过滤器,用于获取规则信息
public class RuleInfoAgendaFilter implements AgendaFilter {
@Override
public boolean accept(AgendaItem agendaItem) {
// 获取规则名称
String ruleName = agendaItem.getRule().getName();
// 获取规则优先级
int ruleSalience = agendaItem.getRule().getSalience();
// 获取规则所在的包名
String rulePackage = agendaItem.getRule().getPackageName();
System.out.println("规则名称:" + ruleName);
System.out.println("规则优先级:" + ruleSalience);
System.out.println("规则包名:" + rulePackage);
// 返回true表示允许规则执行,返回false会跳过该规则
return true;
}
}
之后在调用fireAllRules时传入自定义的过滤器,就可以在规则触发过程中获取Agenda中的规则信息:
// 使用自定义过滤器触发规则 kieSession.fireAllRules(new RuleInfoAgendaFilter());
3. 直接获取Agenda中的规则队列
如果需要在规则触发前或者触发后获取Agenda中的所有规则,可以通过KieSession的getAgenda方法拿到Agenda实例,再获取其中的AgendaItem集合:
import org.kie.api.runtime.rule.Agenda;
// 获取Agenda实例
Agenda agenda = kieSession.getAgenda();
// 获取Agenda中所有的规则项(Drools 8中可通过迭代方式获取)
Iterable<AgendaItem> agendaItems = agenda.getAgendaItems();
for (AgendaItem item : agendaItems) {
System.out.println("Agenda中的规则:" + item.getRule().getName());
}
注意事项
- Agenda中的规则项只有在规则条件被满足时才会被加入,所以需要在插入事实对象之后再获取Agenda内容。
- 如果规则已经执行完毕,Agenda中的对应规则项会被移除,此时无法再获取到已执行过的规则信息。
- 自定义
AgendaFilter时如果返回false,对应的规则会被从Agenda中移除,不会执行,需要根据业务需求合理设置返回值。
完整示例代码
以下是一个完整的Drools 8从Agenda获取规则信息的示例,包含规则文件和执行代码:
规则文件rules.drl内容:
package com.example.rules
import com.example.Order
rule "订单金额大于300优惠规则"
salience 10
when
$order : Order(amount > 300)
then
System.out.println("触发订单优惠规则");
end
rule "订单金额大于500额外优惠规则"
salience 5
when
$order : Order(amount > 500)
then
System.out.println("触发额外优惠规则");
end
执行代码:
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
public class DroolsAgendaDemo {
public static void main(String[] args) {
KieServices kieServices = KieServices.Factory.get();
KieContainer kieContainer = kieServices.getKieClasspathContainer();
KieSession kieSession = kieContainer.newKieSession();
// 插入事实对象
Order order = new Order(600);
kieSession.insert(order);
// 使用过滤器获取Agenda规则信息并执行规则
System.out.println("通过过滤器获取规则信息:");
kieSession.fireAllRules(new RuleInfoAgendaFilter());
// 再次获取Agenda中的规则(此时规则已执行,队列为空)
System.out.println("规则执行后Agenda中的规则:");
Iterable<org.kie.api.runtime.rule.AgendaItem> items = kieSession.getAgenda().getAgendaItems();
for (org.kie.api.runtime.rule.AgendaItem item : items) {
System.out.println(item.getRule().getName());
}
kieSession.dispose();
}
}
运行上述代码后,会先通过过滤器输出Agenda中两个规则的名称、优先级和包名,然后执行规则,规则执行后Agenda队列清空,再次获取时不会有输出。
Drools_8Agenda规则获取KieSession修改时间:2026-06-16 23:00:32