深入了解Drools

深入了解Drools

简单介绍

笔者正在做风控系统,风控系统里边存在非常多的规则(比如:age < 16 || age > 50 -> REJECT )。最便捷的实现就是用 if-else 来写,但是随着规则的增加以及需求的变动,代码将变得越来越难阅读和变动。这时候就要引入Drools等规则引擎了。Drools就是为了解决业务代码和业务规则分离的引擎。

开发环境搭建

网上一般都是eclipse下的教程,这里讲下intellij下的教程。

好了,就这么点步骤,就是如此简单。

Hello Drools

下面立马上手Hello Drools。实现需求:判断一个人的 age < 16 || age > 50 的时候,打印年龄不符合要求。

  • 建立工程
     就是典型的maven工程,除外需要做以下事情:
  1. 导入drools有关jar包。就是droolsjbpm-tools-distribution-7.3.0.Final.zip解压出来后的binaries下的jar包。
  2. 新建配置文件/src/resources/META-INF/kmodule.xml
  3. 新建drools规则文件/src/resources/rules/age.drl
    工程搭建完毕,效果如图:
image.png
  • 开始编写代码
    • kmodule.xml
<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://jboss.org/kie/6.0.0/kmodule">
    <kbase name="rules" packages="rules">
        <ksession name="myAgeSession"/>
    </kbase>
</kmodule>
    • com.hello.Person
package com.hello;

/**
 * Created by Duval Yang
 * CurrentTime : 2017-10-23 14:45.
 */
public class Person {
    
    private Integer age ;    
    private String name ;
    
    public Person(String name ,Integer age){
        this.age = age;
        this.name = name;
    }
  //省略setter  getter
    
}
    • age.drl
import com.hello.Person               // 导入类

dialect  "mvel"

rule "age"                                      // 规则名,唯一
    when
        $person : Person(age<16 || age>50)     //规则的条件部分
    then
        System.out.println("这个人的年龄不符合要求!");   
end

OK .就这么点代码,记住将各种资源文件设为resources(右键可以设置你懂的,不然运行会报各种空指针)。现在用junit 测试下:

/**
 * Created by Duval Yang
 * CurrentTime : 2017-10-23 14:52.
 */
public class PersonTest {
    private static KieContainer container = null;
    private KieSession statefulKieSession = null;

    @org.junit.Test
    public void test() {
        KieServices kieServices = KieServices.Factory.get();
        container = kieServices.getKieClasspathContainer();
        statefulKieSession = container.newKieSession("myAgeSession");
        Person person = new Person("duval yang",12);
        statefulKieSession.insert(person);
        statefulKieSession.fireAllRules();
        statefulKieSession.dispose();
    }
}


好的,Hello Drools 完成了,总结下:
一个完整的drools项目需要:标准的maven项目、kmodule.xml、drl文件、Java代码中切入点。

Drools开发必知

很多琐碎的东西,我就不重复造轮子了.

  • API 和 kmodule文件
    http://blog.csdn.net/u012373815/article/details/53907340

  • Stateless && Stateful
    drools 的session分为有状态和无状态两种。网上的解释很多,我就讲讲我的理解:stateful 可以通过insert等方法插入fact,并且取得一个句柄,通过这个句柄可以多次更新fact从而触发规则。如:

        FactHandle handle = statefulKieSession.insert(account);
        account.setBalance(111.0);
        statefulKieSession.update(handle,account);

stateless 类似于一个函数调用,通过execute方法传入fact,去匹配规则,执行特定的逻辑获得结果。例如:

session.execute(Arrays.asList(new Object[]{routeResult,featureManager.getFreeFeatures(),accessManager,this}));
又或者,执行完获得结果:
List<Command> cmds = new ArrayList<>();
cmds.add( CommandFactory.newInsert(routeResult,"routeResult"));        cmds.add(CommandFactory.newInsert(featureManager.getFreeFeatures(),"freeFeature"));
cmds.add(CommandFactory.newInsert(accessManager,"accessManager"));
cmds.add(CommandFactory.newInsert(this,"router"));
ExecutionResults results = statelessKieSession.execute( CommandFactory.newBatchExecution( cmds ) );

Drools参数

  • salience 定义规则的优先级,数字越大优先级越高,默认0。如salience 88.1
  • no-loop Drools 的RHS 改变了LHS 的条件,会导致这条规则重新被匹配去执行。为了避免drools规则的自身死循环,可以加这个参数。使用如: no-loop true
  • agenda-group STRING定义一个组,当这个组被setFocus的时候,会将整个组压入栈中。执行的时候从栈中取。使用如:agenda-group "Route-AgeRange"。除了可以在java代码中做这个动作,还可以在RHS中做,如:
kcontext.getKieRuntime().getAgenda().getAgendaGroup("Route-AgeRange").setFocus();
  • lock-on-active 一个组里的多条规则都可以设置这个标志,当所有使用了这个标志的规则中的某一条成功触发后,会阻止其他规则的触发执行。

  • 宏函数 insert、update、retract 都可以对fact进行操作,这些动作有可能导致rule的重新匹配

  • import static 导入某个java类的方法

ps.可能是drools这玩意儿比较繁琐,所以官网文档灰常冗长,很多坑都要自己写demo 慢慢踩。

参考资料:
[1] https://docs.jboss.org/drools/release/7.3.0.Final/drools-docs/html_single/index.html
[2] https://geosmart.github.io/2016/08/22/Drools%E5%AD%A6%E4%B9%A0%E7%AC%94%E8%AE%B0/

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,716评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,558评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,431评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,127评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,511评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,692评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,915评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,664评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,412评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,616评论 2 245
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,105评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,424评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,098评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,096评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,869评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,748评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,641评论 2 271

推荐阅读更多精彩内容