1、背景

在咱们编写drools规定文件的过程中,可能会编写好多规定。drools引擎在模式匹配的时候,可能一下子激活了好多规定,然而我只想执行某个指定的规定,那么这个时候该怎么操作呢?

2、计划

2.1 通过AgendaFilter来实现

咱们晓得,在drools模式匹配的时候,会将所有的规定进行匹配,匹配胜利的规定会放入到Agenda(议程)中,而fireAllRules(AgendaFilter)办法,能够传递一个AgendaFilterAgenda中的激活的规定进行过滤。

2.2 通过entry-point来实现

应用entry-point能够定义模式的数据源对应的入口点或事件流。这个不能齐全实现,只是提供一个思路。

举个例子:

Api(api == "/users/info" ) from entry-point "first-entry-point"
Api api = new Api("/users/info", 100);EntryPoint entryPoint = kieSession.getEntryPoint("second-entry-point");entryPoint.insert(api);kieSession.fireAllRules();

下面这个例子,尽管工作内存中存在Api这个对象,然而因为 规定中的 entry-point和java代码中的entry-point不统一,规定是没有匹配胜利的。

3、实现

此处咱们通过 AgendaFilter来实现具体调用某个具体的规定。

3.1 需要

咱们存在一个Api(api,invokedCnt)对象

规定一:工作内存中存在Api对象,且属性api=="/users/info"
规定二:工作内存中存在Api对象,且属性invokedCnt > 10

咱们向工作内存中插入一个 Api("/users/info",100),此时规定一和规定二都会匹配到,然而我只想执行规定二。

3.2 drl 文件编写

package rulesimport com.huan.drools.Apirule "rule_agenda_filter_01"    when        $api: Api(api == "/users/info" )    then        System.out.println("以后执行的规定是: " + drools.getRule().getName());endrule "rule_agenda_filter_02"    when        $api: Api(invokedCnt > 10)    then        System.out.println("以后执行的规定是: " + drools.getRule().getName());end

3.3 局部java代码

Api api = new Api("/users/info", 100);kieSession.insert(api);// 所有模式匹配胜利后的规定回进入到agenda中,而后通过AgendaFilter过滤出须要执行的规定kieSession.fireAllRules(new AgendaFilter() {    @Override    public boolean accept(Match match) {        String ruleName = match.getRule().getName();        return Objects.equals(ruleName, "rule_agenda_filter_02");    }});

能够看到此处通过AgendaFilter进行了规定的过滤,只执行rule_agenda_filter_02规定。

留神: 此处尽管是一个过滤,然而并不意味着只有rule_agenda_filter_02规定是激活的,而是所有满足条件的规定都是激活的。

3.4 运行后果

以后执行的规定是: rule_agenda_filter_02

能够看到实现了咱们想要的后果。

4、残缺代码

https://gitee.com/huan1993/spring-cloud-parent/tree/master/drools/drools-invoked-specify-rule