【转载】Drools学习

Drools使用总结

学习自:
https://blog.csdn.net/column/details/16183.html?&page=1

什么是Drools

  1. Drools是Java编写的一款开源规则引擎,实现了Rete算法对所编写的规则求值,支持声明方式表达业务逻辑。使用DSL(Domain Specific Language)语言来编写业务规则,使得规则通俗易懂,便于学习理解。支持Java代码直接嵌入到规则文件中。
  2. Drools主要分为两个部分:一是Drools规则,二是Drools规则的解释执行。规则的编译与运行要通过Drools 提供的相关API 来实现。而这些API 总体上游可分为三类:规则编译、规则收集和规则的执行。

开发视图

project
src/main/java
xxx.java
xxx.java

src/main/resource
    META-INF
        Kmoudle.xml   drools配置文件
    rules
        xxx.drl    规则文件
        xxx.drt    规则模板

    dtables        决策表     另一种形式的规则文件
        xxx.xls
        xxx.csv       
    process
        xxx.bpmn   流程文件

    datasource
        xxx.txt    规则模板的数据源

pom.xml

kmodule.xml编写

  1. Demo示例
    代码示例:
@Test
    public void testRules() {
        // 构建KieServices
        KieServices ks = KieServices.Factory.get();
        KieContainer kieContainer = ks.getKieClasspathContainer();
        // 获取kmodule.xml中配置中名称为ksession-rule的session,默认为有状态的。
        KieSession kSession = kieContainer.newKieSession("ksession-rule");

        Product product = new Product();
        product.setType(Product.GOLD);

        kSession.insert(product);
        int count = kSession.fireAllRules();
        System.out.println("命中了" + count + "条规则!");
        System.out.println("商品" +product.getType() + "的商品折扣为" + product.getDiscount() + "%。");

    }

规则文件示例

package com.rules

import com.secbro.drools.model.Product

rule Offer4Diamond
    when
        productObject : Product(type == Product.DIAMOND)
    then
        productObject.setDiscount(15);
    end
rule Offer4Gold
    when
        productObject: Product(type == Product.GOLD)
    then
        productObject.setDiscount(25);
    end

Model示例

/**
 * 产品类
 * Created by zhuzs on 2017/7/4.
 */
public class Product {

    public static final String DIAMOND = "DIAMOND"; // 钻石

    public static final String GOLD = "GOLD"; // 黄金

    private String type;

    private int discount;
    // 省略getter/setter方法
}

kmodule.xml示例

<?xml version="1.0" encoding="UTF-8"?>
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
    <kbase name="rules" packages="com.rules">
        <ksession name="ksession-rule"/>
    </kbase>
</kmodule>
  • 内容说明
    • Kmodule中可以包含一个到多个kbase,分别对应drl的规则文件。
    • Kbase需要一个唯一的name,可以取任意字符串。
    • packages为drl文件所在resource目录下的路径。注意区分drl文件中的package与此处的package不一定相同。多个包用逗号分隔。默认情况下会扫描resources目录下所有(包含子目录)规则文件。
    • kbase的default属性,标示当前KieBase是不是默认的,如果是默认的则不用名称就可以查找到该KieBase,但每个module最多只能有一个默认KieBase。
    • kbase下面可以有一个或多个ksession,ksession的name属性必须设置,且必须唯一。

kbase的属性:

属性名默认值合法的值描述
namenoneanyKieBase的名称,这个属性是强制的,必须设置。
includesnone逗号分隔的KieBase名称列表意味着本KieBase将会包含所有include的KieBase的rule、process定义制品文件。非强制属性。
packagesall逗号分隔的字符串列表默认情况下将包含resources目录下面(子目录)的所有规则文件。也可以指定具体目录下面的规则文件,通过逗号可以包含多个目录下的文件。
defaultfalsetrue, false表示当前KieBase是不是默认的,如果是默认的话,不用名称就可以查找到该KieBase,但是每一个module最多只能有一个KieBase。
equalsBehavioridentityidentity,equality顾名思义就是定义“equals”(等于)的行为,这个equals是针对Fact(事实)的,当插入一个Fact到Working Memory中的时候,Drools引擎会检查该Fact是否已经存在,如果存在的话就使用已有的FactHandle,否则就创建新的。而判断Fact是否存在的依据通过该属性定义的方式来进行的:设置成 identity,就是判断对象是否存在,可以理解为用==判断,看是否是同一个对象; 如果该属性设置成 equality的话,就是通过Fact对象的equals方法来判断。
eventProcessingModecloudcloud, stream当以云模式编译时,KieBase将事件视为正常事实,而在流模式下允许对其进行时间推理。
declarativeAgendadisableddisabled,enabled这是一个高级功能开关,打开后规则将可以控制一些规则的执行与否。

ksession的属性

属性名默认值合法的值描述
namenoneanyKieSession的名称,该值必须唯一,也是强制的,必须设置。
typestatefulstateful, stateless定义该session到底是有状态(stateful)的还是无状态(stateless)的,有状态的session可以利用Working Memory执行多次,而无状态的则只能执行一次。
defaultfalsetrue, false定义该session是否是默认的,如果是默认的话则可以不用通过session的name来创建session,在同一个module中最多只能有一个默认的session。
clockTyperealtimerealtime,pseudo定义时钟类型,用在事件处理上面,在复合事件处理上会用到,其中realtime表示用的是系统时钟,而pseudo则是用在单元测试时模拟用的。
beliefSystemsimplesimple,defeasible, jtms定义KieSession使用的belief System的类型。

## KIE讲解
### 什么是KIE
KIE(Knowledge Is Everything) 知识就是一切的简称JBoss一系列项目的总称
结构图

### KIE的生命周期
无论是Drools还是JBPM,生命周期都包含以下部分:
+ 编写:编写规则文件,比如:DRL,BPMN2、决策表、实体类等。
+ 构建:构建一个可以发布部署的组件,对于KIE来说是JAR文件。
+ 测试:部署之前对规则进行测试。
+ 部署:利用Maven仓库将jar部署到应用程序。
+ 使用:程序加载jar文件,通过KieContainer对其进行解析创建KieSession。
+ 执行:通过KieSession对象的API与Drools引擎进行交互,执行规则。
+ 交互:用户通过命令行或者UI与引擎进行交互。
+ 管理:管理KieSession或者KieContainer对象。

Fact对象

  • Fact对象是指在使用Drools规则时,将一个普通的JavaBean对象插入到规则引擎的WorkingMemory当中的对象。规则可以对Fact对象进行任意的读写操作。
  • Fact对象不是对原对象的clone,而是传入对象的引用。规则在进行计算时需要的应用系统数据设置在Fact对象当中,这样规则就可以通过对Fact对象数据的读写实现对应用数据的读写操作。
  • Fact对象通常是一个具有getter和setter方法的POJO对象

KIE API解析

示例demo

// 通过单例创建KieServices
KieServices kieServices = KieServices.Factory.get();
// 获取KieContainer
KieContainer kieContainer = kieServices.getKieClasspathContainer();

// 获取KieBase
KieBase kieBase = kieContainer.getKieBase();
// 创建KieSession
KieSession kieSession = kieContainer.newKieSession("session-name");
  1. KieServices
    该接口提供了很多方法,可以通过这些方法访问KIE关于构建和运行的相关对象,比如说可以获取KieContainer,利用KieContainer来访问KBase和KSession等信息;可以获取KieRepository对象,利用KieRepository来管理KieModule等。
    KieServices就是一个中心,通过它来获取的各种对象来完成规则构建、管理和执行等操作。
    • KieContainer
      可以理解KieContainer就是一个KieBase的容器。提供了获取KieBase的方法和创建KieSession的方法。其中获取KieSession的方法内部依旧通过KieBase来创建KieSession。
    • KieBase
      KieBase就是一个知识仓库,包含了若干的规则、流程、方法等,在Drools中主要就是规则和方法,KieBase本身并不包含运行时的数据之类的,如果需要执行规则KieBase中的规则的话,就需要根据KieBase创建KieSession。
    • KieSession
      KieSession就是一个跟Drools引擎打交道的会话,其基于KieBase创建,它会包含运行时数据,包含“事实Fact”,并对运行时数据实时进行规则运算。通过KieContainer创建KieSession是一种较为方便的做法,其本质上是从KieBase中创建出来的。KieSession就是应用程序跟规则引擎进行交互的会话通道。
      创建KieBase是一个成本非常高的事情,KieBase会建立知识(规则、流程)仓库,而创建KieSession则是一个成本非常低的事情,所以KieBase会建立缓存,而KieSession则不必。
    • KieRepository
      KieRepository是一个单例对象,它是存放KieModule的仓库,KieModule由kmodule.xml文件定义(当然不仅仅只是用它来定义)。
    • KieProject
      KieContainer通过KieProject来初始化、构造KieModule,并将KieModule存放到KieRepository中,然后KieContainer可以通过KieProject来查找KieModule定义的信息,并根据这些信息构造KieBase和KieSession。
    • ClasspathKieProject
      ClasspathKieProject实现了KieProject接口,它提供了根据类路径中的META-INF/kmodule.xml文件构造KieModule的能力,是基于Maven构造Drools组件的基本保障之一。意味着只要按照前面提到过的Maven工程结构组织我们的规则文件或流程文件,只用很少的代码完成模型的加载和构建

规则文件编写

标准规则文件的结构如下:

  • package package-name
  • imports
  • globals
  • functions
  • queries
  • rules

详解

  1. package
    在一个规则文件当中package是必须的,而且必须放置在文件的第一行。package 的名字是随意的,不必必须对应物理路径,这里跟java的package的概念不同,只是逻辑上的区分,但建议与文件路径一致。同一的package下定义的function和query等可以直接使用。
  2. import
    导入规则文件需要的外部变量,使用方法跟java相同。像java的是import一样,还可以导入类中的某一个可访问的静态方法。(特别注意的是,某些教程中提示import引入静态方法是不同于java的一方面,可能是作者没有用过java的静态方法引入。)另外,目前针对Drools7版本,static和function关键字的效果是一样的。
    • rules
      定义一个条规则。rule “ruleName”。一条规则包含三部分:属性部分条件部分结果部分。rule规则以rule开头,以end结尾。
    • 属性部分:定义当前规则执行的一些属性等,比如是否可被重复执行、过期时间、生效时间等。
    • 条件部分:简称LHS,即Left Hand Side。定义当前规则的条件,处于when和then之间。如when Message();判断当前workingMemory中是否存在Message对象。LHS中,可包含0~n个条件,如果没有条件,默认为eval(true),也就是始终返回 true。
    • 结果部分:简称RHS,即Right Hand Side,处于then和end之间,用于处理满足条件之后的业务逻辑。可以使用LHS部分定义的变量名、设置的全局变量、或者是直接编写Java 代码(但不建议)。
    • name
      紧跟在rule关键字后面,可以是一个引号(单引或双引)包含的字符串,可以包含空格等字符,如果字符串只包含数字、字母下划线则可以不用引号,但是不推荐
    • when
      当when条件满足时才会执行then
    • then
      当条件满足时执行的动作
标准规则的结构示例:
rule "name"
    attributes
    when
        LHS
    then
        RHS
    end

#

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值