专注于快乐的事情

Drools初步学习

简介

何为规则引擎

规则引擎(rule engine)是指将复杂的业务逻辑抽象成规则,然后使用特定的算法(比如Rete)对规则进行求值等操作。简单点说,规则引擎就是实现复杂业务逻辑的框架。

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

引入业务规则技术的目的

对系统的使用人员

  • 把业务策略(规则)的创建、修改和维护的权利交给业务经理
  • 提高业务灵活性
  • 加强业务处理的透明度,业务规则可以被管理
  • 减少对IT人员的依赖程度
  • 避免将来升级的风险

对IT开发人员

  • 简化系统架构,优化应用
  • 提高系统的可维护性和维护成本
  • 方便系统的整合
  • 减少编写“硬代码”业务规则的成本和风险

Drools简介

Drools是一款基于Java的开源规则引擎,以将复杂多变的规则从硬编码中解放出来,以规则脚本的形式存放在文件中,使得规则的变更不需要修正代码重启机器就可以立即在线上环境生效。

Drools推出了一套新的基于KIE(Knowledge Is Everything 知识就是一切)概念的API,其目的是将之前版本中对规则引擎繁琐的调用和加载过程加以简化。

Drools的基本工作过程

规则基本过程
Drools执行时传递进去数据,用于规则的检查,调用外部接口,同时还可能需要获取到规则执行完毕后得到的结果。
在drools中,这个传递数据进去的对象,术语叫Fact对象。Fact对象是一个普通的java bean,规则中可以对当前对象进行任何的读写操作,调用该对象提供的方法。

规则:LHS(Left Hand Side)部分为条件分支逻辑。

在 LHS 当中,可以包含 0~n 个条件,如果 LHS 部分没空的话,那么引擎会自动添加一个eval(true)的条件。

RHS(Right Hand Side)为执行逻辑。
在RHS当中可以使用LHS 部分当中定义的绑定变量名、设置的全局变量、或者是直接编写Java代码。

结果对象:规则处理完毕后的结果。需要支持自定义类型或者简单类型(Integer、Long、Float、Double、Short、String、Boolean等)

##第一个程序

###建立一个maven工程,pom如下

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.fir.drools</groupId>
  <artifactId>drools-moudles</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>jar</packaging>

  <name>drools-moudles</name>
  <url>http://maven.apache.org</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- drools 规则引擎 版本 -->
    <drools.version>6.4.0.Final</drools.version>
    <spring.version>4.2.6.RELEASE</spring.version>
    <log4j2.version>2.5</log4j2.version>
  </properties>
  <!-- 依赖项定义 -->
  <dependencies>
    <!-- start drools -->
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-core</artifactId>
      <version>${drools.version}</version>
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-compiler</artifactId>
      <version>${drools.version}</version>
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-decisiontables</artifactId>
      <version>${drools.version}</version>
    </dependency>

    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-workbench-models-guided-template</artifactId>
      <version>${drools.version}</version>
    </dependency>

    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-simulator</artifactId>
      <version>${drools.version}</version>
    </dependency>

    <dependency>
      <groupId>org.jbpm</groupId>
      <artifactId>jbpm-flow-builder</artifactId>
      <version>${drools.version}</version>
    </dependency>

    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-spring</artifactId>
      <version>${drools.version}</version>
    </dependency>

    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-ci</artifactId>
      <version>${drools.version}</version>
    </dependency>
    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-internal</artifactId>
      <version>${drools.version}</version>
    </dependency>
    <dependency>
      <groupId>org.kie</groupId>
      <artifactId>kie-api</artifactId>
      <version>${drools.version}</version>
    </dependency>

    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-workbench-models-guided-dtable</artifactId>
      <version>${drools.version}</version>
    </dependency>
    <dependency>
      <groupId>org.drools</groupId>
      <artifactId>drools-templates</artifactId>
      <version>${drools.version}</version>
    </dependency>
    <!-- end drools -->
  </dependencies>
    <build>
        <testResources>
            <testResource>
                <directory>
                    ${project.basedir}/src/main/resources
                </directory>
            </testResource>
        </testResources>
      <plugins>
        <plugin>
          <groupId>org.apache.maven.plugins</groupId>
          <artifactId>maven-compiler-plugin</artifactId>
          <configuration>
            <source>1.7</source>
            <target>1.7</target>
          </configuration>
        </plugin>
      </plugins>
    </build>
</project>

编辑Kmodule.xml

新建kmodule.xml文件放到src/main/resources/META-INF/文件夹下

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

编辑一个规则文件

在src/main/resources/rules/testwrod/下新建一个Person.drl文件如下:

package rules.testwrod

import com.drools.test.Person
rule test001
    when
        $p:Person(name=="张三",age==30);
    then
      $p.setName("李四");
      System.out.println("改完后的名字"+$p.getName());
end

创建一个java文件

package com.drools.test; /**
 * Created by ww on 17/8/29.
 */
import org.kie.api.KieServices;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;

public class TestWrod{
    public static void main(String[] args) {
        KieServices kss = KieServices.Factory.get();
        //从classpath中读取kmodule,创建KieContainder容器
        KieContainer kc = kss.getKieClasspathContainer();
        //kieContainer根据kmodule.xml定义的ksession的名称找到KieSession的定义,然后创建一个KieSession的实例
        KieSession ks =kc.newKieSession("session");

        //Fact对象
        Person person=new Person("张三",30);
        FactHandle insert = ks.insert(person);

        //KieSession就是一个到规则引擎的链接,通过它就可以跟规则引擎通讯,并且发起执行规则的操作
        int count = ks.fireAllRules();
        //最后将kiesession连接关闭
        System.out.println("总执行了"+count+"条规则");
        ks.dispose();
    }
}

运行java程序,查看结果

改完后的名字李四
总执行了1条规则

表示执行成功。

Drools语法学习

复杂一点的语法

rule "rule1"
     when
     $customer:Customer(age>20,gender=='male')
     Order(customer==$customer,price>1000)
    then
        ....
end

第一个:pattern(模式) 有三个约束
1、 对象 类型必须是 Cutomer;
2、Cutomer 的 age 要大于 20
3、Cutomer 的 gender 要是 male
第二个:pattern(模式) 有三个约束
1、 对象类型必须是 Order;
2、 Order 对应的 Cutomer 必须是前面的那个 Customer
3、 当前这个 Order 的 price 要大于 1000

这两个 pattern 没有符号连接,在 Drools 当中在 pattern 中没有连接符号,那么就用 and 来作为默认连接,所以在该规则的 LHS 部分 中两个pattern(模式)只有都满足了才会返回 true。
对于对象内部的多个约束可以采用&&(and)、||(or)和,(and)来连接。&&,不能混用

规则的属性

Salience优先级

作用是用来设置规则执行的优先级, salience 属性的值是一个数字,数字越大执行优先级越高,同时它的值可以是一个负数。默认情况下,规则的 salience 默认值为 0

package rules.testwrod

rule test001
salience 2
    when
    then
        System.out.println("执行test001");
end

rule test002
salience 1
    when
    then
        System.out.println("执行test002");
end

no-loop防止死循环

date-effective日期比较小于等于

该属性是用来控制规则只有在到达后才会触发

date-expires日期比较大于

date-expires 的作用是用来设置规则的有效期

Enabled是否可用

lock-on-active 规则只执行一次

activation-group分组

具有相同 activation-group 属性的规则中只要有一个会被执行,其它的规则都将不再执行。

agenda-group议程分组

引擎在调用这些设置了 agenda-group 属性的规则的时候需要显示的指定某个 Agenda Group 得到 Focus(焦点),这样位于该 Agenda Group 当中的规则会才触发执行,否则将不执行。

auto-focus焦点分组

实际应用当中 agenda-group 可以和 auto-focus属性一起使用,这样就不会在代码当中显示的为某个 Agenda Group 设置 setFocus 了。一旦将某个规则的 auto-focus 属性设置为 true,那么即使该规则设置了 agenda-group 属性,我们也不需要在代码当中显示的设置 Agenda Group 的setFocus了。

ruleflow-group规则流

在使用规则流的时候要用到 ruleflow-group属性,在规则流当中通过使用 ruleflow-group 属性的值,从而使用对应的规则,该属性会通过流程的走向确定要执行哪一条规则。

##Drools函数的使用

函数是在你的规则源文件中放置语义代码的一种方法,相对于在普通的 java 类中的方法。
在一条规则的推论(then)部分中调用动作,函数是最有用的,特别是如果反复使用的特殊动作。

package rule.testword
function String hello(String name) {
    return "Hello "+name+"!";
}

rule "using a static function"
when
    eval( true )
then
    System.out.println( hello( "Bob" ) );
end

Drool支持函数导入的应用,import function my.package.Foo.hello

函数不能直接用在when条件里,正确的应该eval(hello("张三functionTest"));

##元数据的定义

##Drools宏函数

Drools当中,在RHS里面,提供了一些对当前 Working Memory 实现快速操作的宏函数或对象,比如insert/insertLogical、update/modify 和 retract 就可以实现对当前 Working Memory 中的 Fact 对象进行新增、修改或者是删除;如果您觉得还要使用 Drools 当中提供的其它方法,那么您还可以使用另一外宏对象 drools,通过该对象可以使用更多的操作当前 Working Memory 的方法;同时Drools还提供了一个名为 kcontext 的宏对象,使我们可以通过该对象直接访问当前 Working Memory 的 KnowledgeRuntime。

参考文章

jboss规则引擎KIE Drools 6.3.0 Final 教程(1)

http://blog.csdn.net/column/details/16183.html?&page=2

评论系统未开启,无法评论!