乐趣区

关于后端:drools执行指定的规则

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 rules

import com.huan.drools.Api

rule "rule_agenda_filter_01"
    when
        $api: Api(api == "/users/info")
    then
        System.out.println("以后执行的规定是:" + drools.getRule().getName());
end

rule "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

退出移动版