规则引擎-drools 框架入门
Drools
Drools is a rule engine, DMN engine and complex event processing (CEP) engine for Java.
适用于Java™和JVM平台的开源规则引擎,DMN引擎和复杂事件处理(CEP)引擎。
Drools是一个业务规则管理系统,具有基于前向链接和后向链接推理的规则引擎,可以快速,可靠地评估业务规则和进行复杂的事件处理。
规则引擎还是创建专家系统的基本构建块,在人工智能中,该专家系统是模拟人类专家的决策能力的计算机系统。
Drools 介绍
Drools 是一个基于Charles Forgy’s的RETE算法的,易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。
业务分析师人员或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。
Drools 是用Java语言编写的开放源码规则引擎,使用Rete算法对所编写的规则求值。
Drools允许使用声明方式表达业务逻辑。可以使用非XML的本地语言编写规则,从而便于学习和理解。
并且,还可以将Java代码直接嵌入到规则文件中,这令Drools的学习更加吸引人。
Drools优点:
- 非常活跃的社区支持
- 易用
- 快速的执行速度
- 在 Java 开发人员中流行
- 与 Java Rule Engine API(JSR 94)兼容
Drools相关概念:
- 事实(Fact):对象之间及对象属性之间的关系
- 规则(rule):是由条件和结论构成的推理语句,一般表示为if…Then。一个规则的if部分称为LHS,then部分称为RHS。
- 模式(module):就是指IF语句的条件。这里IF条件可能是有几个更小的条件组成的大条件。模式就是指的不能在继续分割下去的最小的原子条件。
Drools通过事实、规则和模式相互组合来完成工作,drools在开源规则引擎中使用率最广,但是在国内企业使用偏少,保险、支付行业使用稍多。
入门案例
drools有专门的规则语法drl,就是专门描述活动的规则是如何执行的,按照小明的需求规则如下:
drl
Point-rules.drl 文件内容
package rules import com.neo.drools.entity.Order rule "zero" no-loop true lock-on-active true salience 1 when $s : Order(amout <= 100) then $s.setScore(0); update($s); end rule "add100" no-loop true lock-on-active true salience 1 when $s : Order(amout > 100 && amout <= 500) then $s.setScore(100); update($s); end rule "add500" no-loop true lock-on-active true salience 1 when $s : Order(amout > 500 && amout <= 1000) then $s.setScore(500); update($s); end rule "add1000" no-loop true lock-on-active true salience 1 when $s : Order(amout > 1000) then $s.setScore(1000); update($s); end
package 与Java语言类似,drl的头部需要有package和import的声明,package不必和物理路径一致。
import 导出java Bean的完整路径,也可以将Java静态方法导入调用。
rule 规则名称,需要保持唯一,可以无限次执行。
no-loop 定义当前的规则是否不允许多次循环执行,默认是 false,也就是当前的规则只要满足条件,可以无限次执行。
lock-on-active 将lock-on-active属性的值设置为true,可避免因某些Fact对象被修改而使已经执行过的规则再次被激活执行。
salience 用来设置规则执行的优先级,salience 属性的值是一个数字,数字越大执行优先级越高, 同时它的值可以是一个负数。默认情况下,规则的 salience 默认值为 0。如果不设置规则的 salience 属性,那么执行顺序是随机的。
when 条件语句,就是当到达什么条件的时候
then 根据条件的结果,来执行什么动作
end 规则结束
这个规则文件就是描述了,当符合什么条件的时候,应该去做什么事情,每当规则有变动的时候,我们只需要修改规则文件,然后重新加载即可生效。
kmodule.xml
这里需要有一个配置文件告诉代码规则文件drl在哪里,在drools中这个文件就是kmodule.xml,放置到resources/META-INF目录下。 [xml]
<?xml version="1.0" encoding="UTF-8"?> <kmodule xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.drools.org/xsd/kmodule"> <kbase name="point-rulesKB" packages="rules"> <ksession name="point-rulesKS"/> </kbase> </kmodule>
以下对配置说明进行简单说明:
Kmodule 中可以包含一个到多个 kbase,分别对应 drl 的规则文件。
Kbase 需要一个唯一的 name,可以取任意字符串。
packages 为drl文件所在resource目录下的路径。注意区分drl文件中的package与此处的package不一定相同。多个包用逗号分隔。默认情况下会扫描 resources目录下 所有(包含子目录)规则文件。
kbase的default属性,标示当前KieBase是不是默认的,如果是默认的则不用名称就可以查找到该 KieBase,但每个 module 最多只能有一个默认 KieBase。
kbase 下面可以有一个或多个 ksession, ksession 的 name 属性必须设置,且必须唯一。
代码端
[java]
public static final void main(final String[] args) throws Exception{ KieServices ks = KieServices.Factory.get(); KieContainer kc = ks.getKieClasspathContainer(); execute( kc ); } public static void execute( KieContainer kc ) throws Exception{ KieSession ksession = kc.newKieSession("point-rulesKS"); List<Order> orderList = getInitData(); for (int i = 0; i < orderList.size(); i++) { Order o = orderList.get(i); ksession.insert(o); ksession.fireAllRules(); addScore(o); } ksession.dispose(); }
代码解释:首先通过请求获取 KieServices,通过KieServices获取KieContainer,KieContainer加载规则文件并获取KieSession,KieSession来执行规则引擎,KieSession是一个轻量级组建,每次执行完销毁。
KieContainer是重量级组建可以考虑复用。
原文链接:https://houbb.github.io/2020/05/26/rule-engine-01-drools
关注公众号:程序新视界,一个让你软实力、硬技术同步提升的平台
除非注明,否则均为程序新视界原创文章,转载必须以链接形式标明本文链接