Drools介绍与使用
Drools 是用 Java 语言编写的开放源码规则引擎,使用 Rete 算法对所编写的规则求值。Drools 允许使用声明方式表达业务逻辑。可以使用非 XML 的本地语言编写规则,从而便于学习和理解。并且,还可以将 Java 代码直接嵌入到规则文件中,这令 Drools 的学习更加吸引人。
Drools 还具有其他优点:
- 非常活跃的社区支持
- 易用
- 快速的执行速度
- 在 Java 开发人员中流行
- 与 Java Rule Engine API(JSR 94)兼容
Drools 是业务逻辑集成平台,被分为4个项目:
- Drools Guvnor (BRMS/BPMS):业务规则管理系统
- Drools Expert (rule engine):规则引擎,drools的核心部分
- Drools Flow (process/workflow):工作流引擎
- Drools Fusion (cep/temporal reasoning):事件处理
官网:http://www.drools.org/#
官方文档:http://www.drools.org/learn/documentation.html
Drools语法
规则文件
规则文件可以使用 .drl文件,也可以是xml文件,这里我们使用drl文件

package:对一个规则文件而言,package是必须定义的,必须放在规则文件第一行,package的名字是随意的,不必必须对应物理路径,跟java的package的概念不同,这里只是逻辑上的一种区分
如:
package com.sankuai.meituan.waimai.drools.demo
import:导入规则文件需要使用到的外部规则文件或者变量,这里的使用方法跟java相同,但是不同于java的是,这里的import导入的不仅仅可以是一个类,也可以是这个类中的某一个可访问的静态方法
import com.drools.demo.point.PointDomain;
rule:定义一个具体规则。rule "ruleName"。一个规则可以包含三个部分:
属性部分:定义当前规则执行的一些属性等,比如是否可被重复执行、过期时间、生效时间等。条件部分(LHS):定义当前规则的条件,如 when Message(); 判断当前workingMemory中是否存在Message对象。结果部分(RHS):即当前规则条件满足后执行的操作,可以直接调用Fact对象的方法来操作应用。这里可以写普通java代码

rule "ruleName"
no-loop true
<span class="hljs-keyword">when</span>
$message<span class="hljs-symbol">:Message</span>(status == <span class="hljs-number">0</span>)
<span class="hljs-keyword">then</span>
System.out.println(<span class="hljs-string">"fit"</span>);
$message.setStatus(<span class="hljs-number">1</span>);
update($message);
end
规则详情
属性详情
no-loop:
定义当前的规则是否不允许多次循环执行,默认是false;当前的规则只要满足条件,可以无限次执行。什么情况下会出现一条规则执行过一次又被多次重复执行呢?drools提供了一些api,可以对当前传入workingMemory中的Fact对象进行修改或者个数的增减,比如上述的update方法,就是将当前的workingMemory中的Message类型的Fact对象进行属性更新,这种操作会触发规则的重新匹配执行,可以理解为Fact对象更新了,所以规则需要重新匹配一遍,那么疑问是之前规则执行过并且修改过的那些Fact对象的属性的数据会不会被重置?结果是不会,已经修改过了就不会被重置,update之后,之前的修改都会生效。当然对Fact对象数据的修改并不是一定需要调用update才可以生效,简单的使用set方法设置就可以完成,这里类似于java的引用调用,所以何时使用update是一个需要仔细考虑的问题,一旦不慎,极有可能会造成规则的死循环。上述的no-loop true,即设置当前的规则,只执行一次,如果本身的RHS部分有update等触发规则重新执行的操作,也不要再次执行当前规则。
但是其他的规则会被重新执行,岂不是也会有可能造成多次重复执行,数据紊乱甚至死循环?答案是使用其他的标签限制,也是可以控制的:lock-on-active truelock-on-active:lock-on-active true 通过这个标签,可以控制当前的规则只会被执行一次,因为一个规则的重复执行不一定是本身触发的,也可能是其他规则触发的,所以这个是no-loop的加强版
date-expires:设置规则的过期时间,默认的时间格式:“日-月-年”
date-effective:设置规则的生效时间,时间格式同上。
duration:规则定时,duration 3000,3秒后执行规则
salience:优先级,数值越大越先执行,这个可以控制规则的执行顺序。

条件部分- LHS
- when:规则条件开始。条件可以单个,也可以多个,多个条件一次排列
如:当前规则只有在这三个条件都匹配的时候才会执行RHS部分
when
eval(true)
$customer:Customer()
$message:Message(status==0)
eval(true):是一个默认的api,true 无条件执行,类似于 while(true)
操作符:
>、>=、<、<=、==、!=、contains、not contains、memberOf、not memberOf、matches、not matches

- contains: 对比是否包含操作,操作的被包含目标可以是一个复杂对象也可以是一个简单的值
Person( fullName not contains "Jr" )- not contains:与contains相反。
- memberOf:判断某个Fact属性值是否在某个集合中,与contains不同的是他被比较的对象是一个集合,而contains被比较的对象是单个值或者对象
CheeseCounter( cheese memberOf $matureCheeses )- not memberOf:与memberOf正好相反
- matches:正则表达式匹配
Cheese( type matches "(Buffalo)?\\S*Mozarella" )
注意:就像在Java中,写为字符串的正则表达式需要转义“\”- not matches:与matches正好相反
结果部分- RHS
当规则条件满足,则进入规则结果部分执行,结果部分可以是纯java代码
- then:
then
System.out.println("OK"); //会在控制台打印出ok
end
- insert:往当前workingMemory中插入一个新的Fact对象,会触发规则的再次执行,除非使用no-loop限定
- update:更新
- modify:修改,与update语法不同,结果都是更新操作
- retract:删除
rule "Rule 03"
when
$number : Number( )
not Number( intValue < $number.intValue )
then
System.out.println("Number found with value: " + $number.intValue() );
retract( $number );
end
Drools关键词
| 关键词 | 描述 | 详情 |
|---|---|---|
| lock-on-active | ||
| date-effective | ||
| date-expires | ||
| no-loop | ||
| auto-focus | ||
| activation-group | ||
| agenda-group | ||
| ruleflow-group | ||
| entry-point | ||
| duration | ||
| package | ||
| import | ||
| dialect | ||
| salience | ||
| enabled | ||
| attributes | ||
| rule | ||
| extend | ||
| when | ||
| then | ||
| template | ||
| query | ||
| declare | ||
| function | ||
| global | ||
| eval | ||
| not | ||
| in | ||
| or | ||
| and | ||
| exists | ||
| forall | ||
| accumulate | ||
| collect | ||
| from | ||
| action | ||
| reverse | ||
| result | ||
| end | ||
| over | ||
| init | - |
Drools方法定义
- function
function String hello(String name) {
return "Hello "+name+"!";
}
Drools声明类型
- declare:声明类型
- 声明Class、Enum etc类型
- 声明元数据
声明类类型
declare Address
number : int
streetName : String
city : String
end
声明枚举类型
declare enum DaysOfWeek
SUN("Sunday"),MON("Monday"),TUE("Tuesday"),WED("Wednesday"),THU("Thursday"),FRI("Friday"),SAT("Saturday");
fullName : String
end
声明元数据类型
元数据可以被分配给在Drools中几个不同的结构:
- fact types
- fact attributes
- rules
定义格式:
@metadata_key(metadata_value)
例子:
@author( Bob )
import java.util.Date
declare Person
@author( Bob )
@dateOfCreation( 01-Feb-2009 )
name : String @key @maxLength( 30 )
dateOfBirth : Date address : Address
end
声明元数据类级别 关键词
@role( <fact | event> )
import some.package.StockTick
declare StockTick
@role ( event )
end
@typesafe( <boolean> )@timestamp( <attribute name> )
declare VoiceCall
@role( event )
@timestamp( callDateTime )
end
@duration( <attribute name> )@expires( <time interval> )@propertyChangeSupport@propertyReactive
声明元数据属性级别 关键词
@key
两个方面影响:
根据@key作为类标识符,类比较以 @key 的字段为准根据@key字段生成构造函数
declare Person
firstName : String @key
lastName : String @key
age : int
end
@position
declare Cheese
name : String @position(1)
shop : String @position(2)
price : int @position(0)
end
设计

Drools vs ILog vs Jess vs Mandarax
| 优点 | ||
|---|---|---|
| Drools | 开源、社区非常活跃、易使用、免费、JSR94兼容(JSR94是Java Rule Engine API)、支持Java、强大的工具集 | 只支持一种推理方式、安全性不够 |
| ILog | 性能高(电信领域使用)、易使用 | 商业产品、不开源 |
| Jess | 支持2种推理方式(正向链和反向链)、很强的表示、推理能力、支持AOP | 不开源、无规则管理工具、不易使用 |
| Mandarax | 开源、免费、支持Java | JSR94不兼容(JSR94是Java Rule Engine API)、已经不更新、社区不活跃、并且文档不全 |
推理方式
- 正向链推理:一条由问题开始搜索,并得到其解答的链称为正向链推理。
- 反向链推理:一条由假设回推到支持该假设的事实的链称为反向链推理。
作者 @九都散人
2016 年 5月 6日
参考:
Jess 反向链推理机理及诊断专家系统开发模式研究
http://www.docin.org/p-86340503.html
Drools 6.4 Final 文档
</div>
Drools介绍与使用的更多相关文章
- 小明历险记:规则引擎drools教程一
小明是一家互联网公司的软件工程师,他们公司为了吸引新用户经常会搞活动,小明常常为了做活动加班加点很烦躁,这不今天呀又来了一个活动需求,我们大家一起帮他看看. 小明的烦恼 活动规则是根据用户购买订单的金 ...
- 规则引擎drools封装
一.前言 网上规则引擎drools介绍很多,并且有很多细致的说明,作者也不敢托大说自己的好用,但作者经过2个项目使用过规则引擎后,自己对规则引擎的理解并进行封装,对规则内容及如何使用,有自己的一番实践 ...
- Drools 规则引擎应用
规则引擎-drools 1 .场景 1.1需求 商城系统消费赠送积分 100元以下, 不加分 100元-500元 加100分 500元-1000元 加500分 1000元 以上 加1000分 .... ...
- Drools 规则引擎应用 看这一篇就够了
1 .场景 1.1需求 商城系统消费赠送积分 100元以下, 不加分 100元-500元 加100分 500元-1000元 加500分 1000元 以上 加1000分 ...... 1.2传统做法 1 ...
- Drools Expression 介绍
用好Drools 中的表达式是你的规则引擎能否强大的必要条件 http://docs.jboss.org/drools/release/6.1.0.Final/drools-docs/html_sin ...
- drools语法介绍
这里没有翻译http://docs.jboss.org/drools/release/6.4.0.Final/drools-docs/html_single/index.html上的内容 而是参考了网 ...
- Drools 规则学习
Drools 规则学习 在 Drools 当中,一个标准的规则文件就是一个以“.drl”结尾的文本文件,由于它是一个标准的文本文件,所以可以通过一些记事本工具对其进行打开.查看和编辑.规则是放在规则文 ...
- Drools规则
1.实现业务逻辑和业务规则的分离,实现业务规则的集中管理 2.可以动态的改变业务规则,从而快速响应需求变更 3.业务分析人员也可以参与编辑.维护系统的业务规则 fact:一个普通的JavaBean插入 ...
- 使用规则引擎Drools计算圆周率PI
实际上是使用规则引擎能够更新工作内存区重新匹配规则实现迭代功能. 使用了策略模式实现. <规则引擎与RETE算法介绍> PPT : http://files.cnblogs.com/lov ...
随机推荐
- 清北考前刷题day7早安
- 10.23NOIP模拟题
叉叉题目描述现在有一个字符串,每个字母出现的次数均为偶数.接下来我们把第一次出现的字母 a 和第二次出现的 a 连一条线,第三次出现的和四次出现的字母 a 连一条线,第五次出现的和六次出现的字母 a ...
- 贪心 HDOJ 5355 Cake
好的,数据加强了,wa了 题目传送门 /* 题意:1到n分成m组,每组和相等 贪心:先判断明显不符合的情况,否则肯定有解(可能数据弱?).贪心的思路是按照当前的最大值来取 如果最大值大于所需要的数字, ...
- ACM_校庆素数
校庆素数 Time Limit: 2000/1000ms (Java/Others) Problem Description: 广财建校33年了,如今迎来了她的校庆. 小财最近想在研究素数,她突发奇想 ...
- ACM_Hailstone HOTPO
Hailstone HOTPO Time Limit: 2000/1000ms (Java/Others) Problem Description: The hailstone sequence is ...
- EditText(8)EditText中drawableRight图片的点击事件
参考: http://stackoverflow.com/questions/3554377/handling-click-events-on-a-drawable-within-an-edittex ...
- Storm概念学习系列之storm的雪崩
不多说,直接上干货! Storm的雪崩问题的解决办法1: Storm概念学习系列之并行度与如何提高storm的并行度 Storm的雪崩问题的解决办法2:
- 项目经验——Sql server 数据库的备份和还原____还原数据库提示“介质集有2个介质簇,但只提供了1个。必须提供所有成员” .
在对数据库备份与还原的过程中,我遇到一个问题“介质集有2个介质簇,但只提供了1个.必须提供所有成员”,下面详细的介绍一下遇到问题的经过与问题解决的方法! 一.备份与还原遇到的问题描述与解决方法: 前两 ...
- 数据库–Cobar分布式数据库集群MySQL中间件
运行环境: 主机1:Ubuntu14.04 Desktop + MySQL5.5 + JDK 1.7(HP Z400) 内网IP地址:192.168.137.8 NODE1:Ubuntu 13.04 ...
- Linux的网卡由eth0变成了eth1或eth2,如何修复??
背景:做linux下分布式测试的时候,重新安装了两个linux虚拟机,结果分布式脚本没有做好,分布式也没有做成. 今天想练练linux命令,打开vmware,启动linux1 虚拟机,使用ifconf ...