规则引擎drools的简单使用

规则引擎适用于有复杂多变的规则,如商品满减、积分赠送、考勤规则等

一、引入maven依赖

<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-core</artifactId>
    <version>7.13.0.Final</version>
</dependency>
<dependency>
    <groupId>org.drools</groupId>
    <artifactId>drools-compiler</artifactId>
    <version>7.13.0.Final</version>
</dependency>

  

二、drools有两种执行方式,第一种是基于kmodule.xml、drl配置文件,第二种是动态读取规则

基于kmodule方式

 1)创建Fact,drools中的Fact即是java中的普通的bean,用于传递参数

package com.beyond.odc.entity;

/**
 * Fact java bean
 * @author Hejinsheng
 */
public class Message {

    private String message;

    private String result;

    private int status;

    public String getMessage() {
        return this.message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public int getStatus() {
        return this.status;
    }

    public void setStatus(int status) {
        this.status = status;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }
}

  

 2)在resources/META-INF下创建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="ksession-rules"/>
    </kbase>
</kmodule>

  

3)在resources/rules文件夹下创建规则描述文件rules.drl,内容如下

package rules

import com.beyond.odc.entity.Message;

rule "hello"
    no-loop true
    lock-on-active true
    when
        $message:Message(status==0)
    then
        System.out.println("消息:"+$message.getMessage());
        $message.setResult("hello 响应的消息");
        update($message)
end

rule "byebye"
    no-loop true
    lock-on-active true
    when
        $message:Message(status==1)
    then
        System.out.println("消息:"+$message.getMessage());
        $message.setResult("byebye 响应的消息");
        update($message)
end

  

 4)编写测试文件

public static void main(String[] args) {
       try {

            KieSession kSession = KieContainerFactory.getKieContainer().newKieSession("ksession-rules");

            Message message = new Message();
            message.setMessage("hello");    // 对应drl文件中的rule name,表示要执行的规则
            message.setStatus(0);           // 取message中的某个字段,用户规则文件中的判断是否执行代码块
            kSession.insert(message);       // 将message作为传递的参数传入drools执行
            kSession.fireAllRules();        // 加载规则
            System.out.println("从drools中接收到的消息:"+message.getResult());    // drools中如果有参数响应,可以通过字段获取
        } catch (Throwable t) {
            t.printStackTrace();
        }
}

  

//KieContainerFactory代码片段
public class KieContainerFactory {

    private static KieContainer kieContainer;

    public static KieContainer getKieContainer() {
        if(kieContainer == null){
            // load up the knowledge base
            KieServices ks = KieServices.Factory.get();
            KieContainer kContainer = ks.getKieClasspathContainer();
            kieContainer = kContainer;
        }
        return kieContainer;
    }
}

  

5)执行结果,说明代码已经执行到drools文件中,具体的业务逻辑可以在then后的代码块中实现

进来了,消息:hello
从drools中接收到的消息:hello 响应的消息

  

三、动态方式执行

一般指从数据库或者远程获取的规则描述信息,进行规则执行。动态方式不需要kmodule.xml和drl文件,执行上更加简单

public static void execFromDB(){
        KieSession kSession = null;
        try {
            // 实际情况从数据库根据code查规则,这里模拟写死
            String rule = "package rules\n" +
                    "\n" +
                    "import com.beyond.odc.entity.Message;\n" +
                    "\n" +
                    "rule \"hello\"\n" +
                    "    no-loop true\n" +
                    "    lock-on-active true\n" +
                    "    when\n" +
                    "        $message:Message(status==0)\n" +
                    "    then\n" +
                    "        System.out.println(\"动态执行,消息:\"+$message.getMessage());\n" +
                    "        $message.setResult(\"hello 响应的消息\");\n" +
                    "        update($message)\n" +
                    "end\n" +
                    "\n" +
                    "rule \"byebye\"\n" +
                    "    no-loop true\n" +
                    "    lock-on-active true\n" +
                    "    when\n" +
                    "        $message:Message(status==1)\n" +
                    "    then\n" +
                    "        System.out.println(\"动态执行,消息:\"+$message.getMessage());\n" +
                    "        $message.setResult(\"byebye 响应的消息\");\n" +
                    "        update($message)\n" +
                    "end";

            KnowledgeBuilder kb = KnowledgeBuilderFactory.newKnowledgeBuilder();
            kb.add(ResourceFactory.newByteArrayResource(rule.getBytes("utf-8")), ResourceType.DRL);

            // 检查规则正确性
            KnowledgeBuilderErrors errors = kb.getErrors();
            for (KnowledgeBuilderError error : errors) {
                System.out.println("规则文件正确性有误:{}" + error);
            }
            InternalKnowledgeBase kBase = KnowledgeBaseFactory.newKnowledgeBase();
            kBase.addPackages(kb.getKnowledgePackages());

            // 执行规则
            kSession = kBase.newKieSession();
            // fact
            Message fact = new Message();
            fact.setMessage("byebye");
            fact.setStatus(1);
            kSession.insert(fact);
            kSession.fireAllRules();
            System.out.println("从drools规则中接收到的消息:"+fact.getResult());
        } catch (Exception e) {
            System.out.println("规则执行异常:{}"+e);
        } finally {
            if (null != kSession)
                kSession.dispose();
        }

    }

  执行结果如下:

动态执行,消息:byebye
从drools规则中接收到的消息:byebye 响应的消息

  

 

posted @ 2018-10-30 14:35  hejinsheng  阅读(1169)  评论(0编辑  收藏  举报