Drools简单入门

因为在项目要用到Drools,所以下面写了一个简单的例子学习入门。

一、Drools简介:

JBoss Rules 的前身是Codehaus的一个开源项目叫 Drools。最近被纳入JBoss门下,更名为JBoss Rules,成为了JBoss应用服务器的规则引擎。

Drools 是为 Java 量身定制的基于Charles Forgy的RETE算法的规则引擎的实现。具有了OO接口的RETE,使得商业规则有了更自然的表达。

Drools 的用 XML 的<Conditons>、<Consequence> 节点表达If–Then句式,而里面可以嵌入上述语言的代码作为判断语句和执行语句。

其中 Java 代码会使用Antlr进行解释,而 Groovy 和 Python 本身就是脚本语言,可以直接调用。

Drools 的聪明之处在于,用 XML 节点来规范 If–Then 句式和事实的定义,使引擎干起活来很舒服。

而使用 Java,Groovy等原生语言来做判断和执行语句,让程序员很容易过渡、移植,学习曲线很低。

二、几个重要概念

  • 事实(Fact):对象之间及对象属性之间的关系
  • 规则(rule):是由条件和结论构成的推理语句,一般表示为if...Then。一个规则的if部分称为LHS,then部分称为RHS。
  • 模式(module):就是指IF语句的条件。这里IF条件可能是有几个更小的条件组成的大条件。模式就是指的不能在继续分割下去的最小的原子条件。

三、.drl 文件内容

package com.rules

import com.drools.model.Person
import com.drools.model.Goods

rule "test-drools-older than 60"

when
     no-loop true
     lock-on-active true
     salience 1
     $Goods : Goods(person.age > 60)
then
     $Goods.setDiscount(80);
     System.out.println("test-drools-older than 60 " + $Goods.getPerson().getAge());
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

kmodule.xml的作用就是告诉代码规则文件drl在哪里,在drools中这个文件就是kmodule.xml,放置到resources/META-INF目录下。kmodule.xml内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="rules">
        <ksession name="all-rules"/>
    </kbase>
</kmodule>

以下对配置说明进行简单说明:

  • Kmodule 中可以包含一个到多个 kbase,分别对应 drl 的规则文件。
  • Kbase 需要一个唯一的 name,可以取任意字符串。
  • packages 为drl文件所在resource目录下的路径。注意区分drl文件中的package与此处的package不一定相同。多个包用逗号分隔。默认情况下会扫描 resources目录下所有(包含子目录)规则文件。
  • kbase的default属性,标示当前KieBase是不是默认的,如果是默认的则不用名称
    就可以查找到该 KieBase,但每个 module 最多只能有一个默认 KieBase。
  • kbase 下面可以有一个或多个 ksession,ksession 的 name 属性必须设置,且必须唯一。

五、下面是一个简单的入门例子

1、首先项目的结构如下

2、引入drools的依赖

    <dependencies>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-core</artifactId>
            <version>7.7.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-compiler</artifactId>
            <version>7.7.0.Final</version>
        </dependency>
        <dependency>
            <groupId>org.drools</groupId>
            <artifactId>drools-templates</artifactId>
            <version>7.7.0.Final</version>
        </dependency>
    </dependencies>

3、创建一个xml,注意一定要放在META-INF文件夹下,drools会自动解析它

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="rules">
        <ksession name="all-rules"/>
    </kbase>
</kmodule>

4、创建实体Goods和Person

5、创建规则droolsRules.drl

package com.rules

import com.drools.model.Person
import com.drools.model.Goods

rule "test-drools-older than 60"

when
     $Goods : Goods(person.age > 60)
then
     $Goods.setDiscount(80);
     System.out.println("test-drools-older than 60 " + $Goods.getPerson().getAge());
 end

 rule "test-drools-other"
 when
     $Goods : Goods(person.age <= 60)
 then
     $Goods.setDiscount(70);
     System.out.println("test-drools-other " + $Goods.getPerson().getAge());
 end

6、测试类

public class DroolsTest {

    public static void main(String[] args) {
        //获取一个实例
        KieServices kieServices = KieServices.Factory.get();
        //默认去读取配置文件
        KieContainer kieContainer = kieServices.getKieClasspathContainer();
        //根据这个名词去获取kieSession
        KieSession kieSession = kieContainer.newKieSession("all-rules");

        Person p1 = new Person();
        p1.setAge(30);
        p1.setName("Tom");
        Goods g1 = new Goods();
        g1.setPerson(p1);

        Person p2 = new Person();
        p2.setAge(70);
        p2.setName("Joy");
        Goods g2 = new Goods();
        g2.setPerson(p2);

        //将person实例放入session中
        kieSession.insert(g1);
        kieSession.insert(g2);

        //开始执行规则,并获取执行了多少条规则
        int count = kieSession.fireAllRules();
        //关闭session
        kieSession.dispose();
        System.out.println("Fire " + count + " rule(s)!");
        System.out.println("The discount of g1 is " + g1.getDiscount() + "%");
        System.out.println("The discount of g2 is " + g2.getDiscount() + "%");

    }
}

7、运行结果

test-drools-older than 60 70
test-drools-other 30
Fire 2 rule(s)!
The discount of g1 is 70%
The discount of g2 is 80%

参考:Drools 规则文件语法概述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值