初探Drools

article/2025/10/1 8:49:02

文章目录

  • 背景
  • 一、Drools基本概念
    • 1.1 规则引擎
    • 1.2 Drools简介
  • 二、Drools基本用法
    • 2.1 规则文件
    • 2.2 配置文件
    • 2.3 数据驱动
  • 三、Drools进阶用法
    • 3.1 DSL语言
    • 3.2 其他
  • 四、Workbench
  • 五、android端集成
  • 六、类比其他Java规则引擎
  • 七、应用场景与展望


背景

笔者最近在研究、使用Java规则引擎Drools,主要工作分两部分:1. Java EE环境下的Drools、Workbench的使用;2. Drools android环境的移植工作,本篇博客主要也是按照这两部分内容分别介绍的。


一、Drools基本概念

1.1 规则引擎

Drools是Java规则引擎,关于规则引擎的定义,笔者从百度百科摘录了如下定义

规则引擎由推理引擎发展而来,是一种嵌入在应用程序中的组件,实现了将业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入,解释业务规则,并根据业务规则做出业务决策。

从规则的定义可知,一个完整的规则引擎应该包含:

  1. 规则定义
  2. 规则解析
  3. 决策执行

笔者调研过各种java规则引擎,大多数轻量级规则引擎包含上述的两种及全部。各类引擎也都是在一种或者多种领域个性化,扩充能力。
规则引擎引入前后架构对比

图1 规则引擎引入前后架构对比

1.2 Drools简介

Drools的定义,笔者也从百度百科摘录了定义,结果如下

Drools(JBoss Rules )具有一个易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。业务分析师或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。

Drools有如下特点:

  1. 完全开源现在仍在持续更新;
  2. 基于Charles Forgy的RETE算法的规则引擎的实现;
  3. 使用XML的、 节点表达If–Then句式,而里面可以嵌入上述语言的代码作为判断语句和执行语句。

Drools规则引擎架构

图2 引擎框架简图

二、Drools基本用法

2.1 规则文件

下面是一个标准的drl文件

// 图书优惠规则
package book.discount
import com.saic.entity.Order
import com.saic.entity.Constantfunction void hello(int price){System.out.println(("cost down "+price));
}
declare Constant endquery "origin price larger than 100"$order : Order( originalPrice > 100 )
end// 规则一:所购图书总价在100元以下的没有优惠
rule RULE_1when$order: Order(originalPrice < 100) // 匹配模式,到规则引擎中(工作内存)查找Order对象,命名为$orderor $order: Order(realPrice >= 500)then$order.setRealPrice($order.getOriginalPrice());System.out.println("成功匹配到规则一,所购图书总价在100元以下无优惠");
end

从一个标准文件,可以看出:

  1. 一个规则文件包含:包名、引用、自定义函数、查询、对象申明、规则体等;
  2. 一个规则体包含规则名LHSRHS;
  3. 绑定变量名:[绑定变量名:Object(Field 约束)];
  4. 规则文件与Java可以实现双向调用;
  5. 有一点需要注意的是,运算符(+、-、*、/、%)与java优先级相同.
    drl文件引用的Java文件如下:
package com.saic.entity;public class Order {private Double originalPrice; // 订单原始价格,即优惠前的价格private Double realPrice; // 订单真实价格,即优惠后的价格public Double getOriginalPrice() {return originalPrice;}public void setOriginalPrice(Double originalPrice) {this.originalPrice = originalPrice;}public Double getRealPrice() {return realPrice;}public void setRealPrice(Double realPrice) {this.realPrice = realPrice;}
}

2.2 配置文件

规则文件创建完成以后,需要配置xml文件方便引擎去识别、加载规则到内存中。对于初学者一般使用kmodule.xml配置引擎信息。Drools还支持一些高阶配置比如change-set。下面内容为一个kmodel.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"><!--name:指定kbase的名称,可以任意,但是需要唯一packages:指定规则文件的目录,需要根据实际情况填写,否则无法加载到规则文件default:指定当前kbase是否为默认--><kbase name="myKbase1" packages="rules"><!--name:指定ksession的名称,可以任意,但需要唯一default:指定当前session是否为默认--><ksession name="ksession-rule" default="true"/></kbase>
</kmodule>
  1. kmodule.xml文件存放在src/main/resources/META-INFO文件夹下。一个kmodule.xml配置中可包含多个KieBase,每一个KieBase都有name属性,可以取任意字符串,但不能重名;
  2. KieBase有一个packages属性,其内容指向src/main/resources目录下文件夹的名称,规则引擎会根据packages定义的内容查找规则文件(文件夹下有子文件夹不会被加载);
  3. 每一个KieSession都有一个名称,名称可以是任意字符串,但不能重复。

2.3 数据驱动

规则创建完毕,规则被装载入内存后,需要数据驱动整个引擎工作,这个数据Drools命名为Fact。规则运算时需要用到应用系统中的数据,将这些对象设置到Fact对象中,然后将其插入Working Memory中,一个Fact通常是一个具有getter方法和setter方法的POJO对象,通过getter方法和setter方法可以方便的对Fact对象进行操作,所以可以通俗的把Fact对象理解为规则与应用系统数据交互的桥梁或者通道。下面事例代码描述了如何操作Fact对象,引擎匹配规则。

public class AccountTest {@Testpublic void testAccount() {KieServices kieServices = KieServices.Factory.get();// 获取Kie容器对象(默认容器对象KieContainer kieContainer = kieServices.getKieClasspathContainer();// 从Kie容器对象中获取会话对象(默认session对象KieSession kieSession = kieContainer.newKieSession();Account account = new Account();account.setBalance(88);kieSession.insert(account);int count = kieSession.fireAllRules();System.out.println("总共执行了" + count + "条规则");kieSession.dispose();}
}

三、Drools进阶用法

3.1 DSL语言

Drools领域语言又称作自然语言,它是业务人员通过dslr文件编写的规则文件,通过文字描述来实现业务规则。DSL是Drools提供的一种可通过非正规的规则语法编写的规则文件,使用DSL领域语言时,需要创建.dsl.dslr两个文件,核心是*.dsl文件。
DSL机制是允许定制conditional expressions(条件表达式LHS)和consequence actions(结果值RHS),也可以替换全局变量。使用DSL功能可以分成下面四步:

  1. 创建规则文件PersonDSL.dsl,代码如下:
[when] There is a person = $p:Person()
[when] - id greater than {id:\d*} = id > {id}
[then] 学校将张三安排到"{className}"=$p.setClassName("{className}");
[then] print = System.out.println("You are beautiful!");
  1. 创建规则文件isDSL.dslr,代码如下:
package rulesTwo;
import com.saic.entity.Person;
expander personDSL.dsl
rule 'test-dsl'whenThere is a person- id greater than 10then学校将张三安排到"3 grade"print
end
  1. 配置kmodule.xml,如下我们的规则文件放在src/main/resources/rulesTwo目录下,我们packages配置为rulesTwo。
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule"><!--name:指定kbase的名称,可以任意,但是需要唯一packages:指定规则文件的目录,需要根据实际情况填写,否则无法加载到规则文件default:指定当前kbase是否为默认--><kbase name="dsl" packages="rulesTwo"><ksession name="isDSL"/></kbase>
</kmodule>
  1. Fact更新,规则匹配代码类似于2.3章节,这里暂不做赘述。

3.2 其他

Drools还有另外一些高级用法:决策表、规则模版、规则流等,受限于篇幅这里暂不做介绍,感兴趣的读者可以自行翻阅相关文档了解。

四、Workbench

Workbench是KIE组件中的元素,也称为KIE-WEB,是Drools-WB与JBPM-WB的集合体,是一个WEB-IDE,是一个可视化的规则编辑器。Workbench功能十分强大,不仅提供一系规则编辑器,还可以编辑JavaBean。

  1. workbench部署:
    Workbench是一个war包,可以部署在tomcat和wildfly中。笔者本地部署的workbench版本为kie-drools-wb-6.5.0.Final,经多轮测试发现该war包只有在tomcat8以下的版本才能正常部署
    Workbench登录后的首页
图3 登录账号后主页面
  1. 编辑
    第一步:创建一个新的空间及项目
    创建WorkbenchJava工程与项目如图4所示。
    创建工程
图4 创建工程与项目

第二步:创建一个Person数据对象和一个决策树
创建Person对象和决策树

图5 决策树与数据对象在workbeanch中的显示
图6描述的是在workbench编辑页面创建Person数据对象,图7描述的是在workbench编辑页面创建javaTree向导决策树。图5为工程列表界面。

创建Person对象

图6:创建Person对象

创建决策树

图7:创建决策树
  1. Workbeanch部署
    点击Build & Deploy按钮将工程编辑成jar包,部署在本地maven仓库。图8描述的是workbench项目部署功能。
    部署
图8:Workbeanch部署
  1. 动态加载
    workbench部署以后,我们的客户端可以调用Drools的KieScanner的依赖包动态更新规则库,事例代码如下所示:
public class TestWorkbench {@Testpublic void testWorkbench() {KieServices kieServices = KieServices.Factory.get();ReleaseId releaseId = kieServices.newReleaseId("com.WorkbenchJava", "Workbench4Java", "1.0.0");KieContainer kieContainer = kieServices.newKieContainer(releaseId);KieScanner kieScanner = kieServices.newKieScanner(kieContainer);kieScanner.start(1000L);while (true) {try {KieSession kieSession = kieContainer.newKieSession();Person person = new Person();person.setAge(30);person.setName("张三");kieSession.insert(person);int count = kieSession.fireAllRules();System.out.println("Java调用workbench,自动扫描共执行了" + count + " 条规则");System.out.println("解决后的结果为: "+ person.getClassName());Thread.sleep(1000L);} catch (Exception ex) {ex.printStackTrace();}}}
}

五、android端集成

Drools为Java EE项目,主要运行在服务器。笔者为android开发,尝试在android端集成Drools相关功能。
笔者的开发的软件环境为:

  1. android 9.0
  2. Drools版本 5.2

笔者在android上实现了android的集成,亲测可以实现规则文件的热更新

六、类比其他Java规则引擎

市面上的Java规则引擎很多,笔者将他们分成两类,重量级和轻量级两类。重量级规则引擎功能完备,依赖较多,轻量级依赖少包的体积小。下面罗列了几个规则引擎及其优点,具体使用哪种引擎需要根据自己的业务需求决定。
1)重量级:

  1. Ilog JRules :最知名商业规则管理系统
  2. Drools:开源,最活跃
  3. Visual Rules:最早国内商业规则管理系统

2)轻量级:

  1. Aviator:
    专用脚本语言AviatorScript
    asm模式与解释器模式
  2. Easy rule:
    支持Java和yml两种方式调用
    支持注解
    支持规则组合
  3. QLExpress:
    支持表达式缓存,性能优秀
    安全可控

七、应用场景与展望

规则引擎应用广泛,之前主要应用在在服务端设备。随着移动互联时代的到来,越来越多的移动设备也是用了规则引擎,使用方式笔者认为大体分为三类:

  1. 自研规则引擎,比如语音DM;
  2. 完全使用开源规则引擎,例android集成Drools,Drools功能完善,但是比较重,学习成本高,灵活度有所欠缺;
  3. 使用规则引擎部分功能,高合汽车场景引擎采用QLExpress做规则判断,其余功能自研,这类方案自由度大一些。

随着智能座舱概念成为主流,越来越多的车载应用需要支持动态配置,规则引擎的引用也是越来越多,使用者需要根据业务需求选择合适的规则引擎。


http://chatgpt.dhexx.cn/article/Qidk77PX.shtml

相关文章

Drools学习01

Drools学习 1.springbootdroolsstringTemplate 1.1主要依赖导入 <!--使用drools的主要依赖--> <dependency><groupId>org.drools</groupId><artifactId>drools-compiler</artifactId><version>7.73.0.Final</version> <…

Drools基础语法

Drools基础语法 规则文件构成 在使用Drools时非常重要的一个工作就是编写规则文件&#xff0c;通常规则文件的后缀为.drl。 drl是Drools Rule Language的缩写。在规则文件中编写具体的规则内容。 一套完整的规则文件内容构成如下&#xff1a; Drools支持的规则文件&#xff…

【Drools一】值得打工人学习的规则引擎Drools

本文主要对Drools的使用业务场景做简单介绍。 规则引擎 规则引擎&#xff1a;全称为业务规则管理系统&#xff0c;英文名为BRMS(即Business Rule Management System)。规则引擎的主要思想是将应用程序中的业务决策部分分离出来&#xff0c;并使用预定义的语义模块编写业务决策…

Drools 入门例子

本人参照drools-4.0.7-examples修改&#xff0c;可以到这个网址去下载&#xff1a;http://www.jboss.org/drools/downloads.html 1:下载4.0版eclipse &#xff1a; eclipse-java-ganymede-win32.zip并解压到D:/eclipse-java-ganymede-win32不需安装 2:下载drools插件 http://ww…

Drools

Drools入门系列&#xff08;一&#xff09;HelloWorldDrools入门系列&#xff08;二&#xff09;HelloWorld详解之Sample.drlDrools入门系列&#xff08;三&#xff09;HelloWorld详解之kmodule.xmlDrools入门系列&#xff08;四&#xff09;HelloWorld详解之JUnit Test类Drool…

规则引擎 Drools

规则引擎 Drools 文章目录 规则引擎 Drools1. 问题引出2. 规则引擎概述2.1 什么是规则引擎2.2 使用规则引擎的优势2.3 规则引擎应用场景2.4 Drools介绍 3.Drools入门案例3.1 业务场景说明3.2 开发实现3.3 小结3.3.1 规则引擎构成3.3.2 相关概念说明3.3.3 规则引擎执行过程3.3.4…

drools学习

drools使用和设置 1.概述举个例子 2.结合maven引入1.引入maven2.创建kmoudule.xml文件3如有需要,安装drools的插件4编写drl规则文件5准备用于测试的po类6编写drools的java接口 3.基本规则 4.组合语法 1.概述 drools是一个规则引擎,什么是规则引擎?就是能够自动将决策树转化为…

drools详解

1、基本的概念 请参考这个链接&#xff0c;差不多的语法感觉都介绍了 drools-api的基本语法链接 2、如何将drl文件配置在数据库中&#xff0c;实现动态加载&#xff1a; package com.neo.drools;import com.neo.drools.model.Message; import org.kie.api.io.ResourceType; i…

Drools基本介绍,入门案例,基本语法

目录 经典需求与场景 需求 传统做法-if 传统做法-策略 问题&#xff1f; 规则引擎 概念 起源 原理--基于 rete 算法的规则引擎 规则引擎应用场景 Drools 介绍 消费赠送积分案例 第一步&#xff1a; 创建工程&#xff0c;引入jar 创建 drools 自动配置类 订单实体…

Drools 简介

序 现实生活中&#xff0c;规则无处不在。对于某些企业级应用&#xff0c;诸如欺诈检测软件&#xff0c;购物车&#xff0c;活动监视器&#xff0c;信用和保密应用之类的系统&#xff0c;经常会有大量的、错综复杂的业务规则配置&#xff0c;而且随着企业管理者的决策变化&…

drools 介绍

1 .场景 1.1需求 商城系统消费赠送积分 100元以下, 不加分 100元-500元 加100分 500元-1000元 加500分 1000元 以上 加1000分 ...... 1.2传统做法 1.2.1 if...else if (order.getAmout() < 100){ order.setScore(0); addScore(order); }else if(order.getAmo…

计组——定点数原码反码补码移码以及它们之间的转换

原码 用尾数表示真值的绝对值&#xff0c;符号位“0/1”对应“正/负” 若机器字长n1位&#xff0c;原码整数的表示范围&#xff1a; − ( 2 n − 1 ) ≤ x ≤ 2 n − 1 {\color{Red} -(2^{n}-1)\leq x\leq 2^{n}-1} −(2n−1)≤x≤2n−1&#xff08;关于原点对称&#xff09;…

数据的表示:原码、反码、补码、移码以及浮点数的运算

前言 复习到数据表示方面相关的知识&#xff0c;所以在这里做一下记录&#xff0c;也方便大家参考。 什么是 R 进制 对于 R 机制&#xff0c;如果要实现与十进制的转换&#xff0c;则使用 按权展开法&#xff0c;其具体操作为&#xff1a; 将 R 进制数的每一位数值用 R k R…

五分钟理解原码补码反码和移码

这是计算机的基本知识了&#xff0c;一定要好好学。哈哈废话不多说&#xff0c;直接进入正题吧。计算机中有无符号数和有符号数两大类。 有符号数就是正负数&#xff0c;在计算机中正好用0和1分别去代表正和负。(ps:好多人不理解机器数和真值&#xff0c;机器数就是把符号数字…

原码、反码、补码、移码的表示

若字长n为8时&#xff0c;那么45的二进制表示0 0101101 &#xff0c;若数值X 1.原码 [X]原&#xff0c;在二进制数值中&#xff0c;正数保持不变&#xff0c;负数符号位置1. 2.反码 [X]反&#xff0c;的正数保持不变 &#xff0c; 负数对数值的绝对值每一位按位求反 3.补码…

关于补码移码各自和原码的联系、来历、功能及I EEE754标准中移码范围问题

最近在学习计算机组成原理时,遇到一些问题,记录在此。 如果你对下面这段话有疑惑或者兴趣&#xff0c;我或许能说点什么你感兴趣的。 真值-128的补码&#xff1a;1000 0000&#xff0c;这个补码本身表示的二进制数&#xff08;无符号&#xff09;是128&#xff0c;其对应着真…

移码的计算方式

规则&#xff1a;对应真值的补码的符号位取反&#xff1b; 计算公式&#xff1a; 式中&#xff1a;x为真值&#xff0c;n为整数的位数&#xff1b; 形式上补码是先减后增的&#xff0c;移码是递增的&#xff1b;根据人类的习惯&#xff0c;移码可以清楚的反映对应真值的大小…

计算机组成原理学习笔记:定点数、浮点数、原码、反码、补码、移码

定点数与浮点数 所谓定点数就是指小数点的位置固定不变而浮点数是小数点的位置是不固定的&#xff0c;会浮动 1 ) 定点数 用熟悉的十进制数来类比&#xff0c;定点数就是我们平时更习惯使用的常规的计数方式&#xff0c;我们会显式的标明小数点的位置Eg: 110.12 2 &#xf…

原码,补码,移码

一、原码 ①最高位为符号位&#xff0c;0表示正数&#xff0c;1表示负数&#xff1b; ②除符号位其它数值部分&#xff0c;就是数值本身绝对值的二进制数&#xff1b; ③负数的原码是在其绝对值得的基础上&#xff0c;符号位变为1&#xff1b; 但是&#xff1a; 0的表示不唯一&…

移码补码原理

计算机中的“数”&#xff0c;花样很多&#xff0c;又是ASCII码、又是BCD码等等&#xff0c;下面&#xff0c;做而论道写了一些关于移码、补码的一些看法&#xff0c;欢迎拍砖。 机器数 计算机中的“数”&#xff0c;其实都不是数字&#xff0c;它们都是一些高、低电平。其中&a…