zoukankan      html  css  js  c++  java
  • Drools 规则引擎环境搭建

    一、关于 drools 规则引擎

    前面写过一篇 Drools 规则引擎相关的文章,这篇文章主要记录一下规则引擎的环境搭建和简单示例。不熟悉 drools 的朋友可以看看这篇文章: 自己写个 Drools 文件语法检查工具——栈的应用之编译器检测语法错误
    介绍的内容:

    • Drools 规则引擎的使用场景
    • Drools 规则引擎的优点
    • Drools的基本工作工程(Fact对象、Drl文件内容、Drools的基础语法)
    • drools 文件的形式
    • Drools 文件语法初步检查

    二 、Drools 的环境搭建及简单示例

    环境: idea + jdk1.8 + gradle
    我用的是 gradle 构建 java 工程的方式、用 maven 构建的可以参考配置

    构造这样一个需求背景,双十一来了,商品打折,假设商品价格 (0,500], 打85折,商品价格 (500, 1000],打8折, 商品价格 (1000,∞), 一律减 300。

    1. 创建项目

    新建一个 gradle 项目,创建包:com.sharpcj,新建类 Product.javaMain.java

    Product.java 文件如下:

    package com.sharpcj;
    
    public class Product {
        private String name;  // 商品名称
        private double prePrice;  // 商品定价
        private double realPrice;  //商品实际售价
    
        public Product() {
        }
    
        public Product(String name, double prePrice) {
            this.name = name;
            this.prePrice = prePrice;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public double getPrePrice() {
            return prePrice;
        }
    
        public void setPrePrice(double prePrice) {
            this.prePrice = prePrice;
        }
    
        public double getRealPrice() {
            return realPrice;
        }
    
        public void setRealPrice(double realPrice) {
            this.realPrice = realPrice;
        }
    }
    
    

    然后在 Main.java 新建 main 方法。

    2. Gradle引入Drools库

    打开 build.gradle 文件,添加相应的插件和依赖

    
    plugins {
        id 'java'
    }
    
    plugins {
        id 'application'
    }
    
    mainClassName = 'com.sharpcj.Main'
    
    group 'com.sharpcj'
    version '1.0-SNAPSHOT'
    
    sourceCompatibility = 1.8
    
    repositories {
        mavenCentral()
    }
    
    dependencies {
        testCompile group: 'junit', name: 'junit', version: '4.12'
        compile group: 'org.kie', name: 'kie-api', version: '7.5.0.Final'
        compile group: 'org.drools', name: 'drools-compiler', version: '7.5.0.Final'
    }
    

    引入 Java 插件,使Gradle可以构建Java代码,同时引入了执行Drools依赖的两个库, 指定了 mainClassName

    3.编写 drools 文件

    resources 目录下面新建包 demo.rules,用来存放 drools 规则文件。然后新建文件 product.drl

    内容如下:

    package com.sharpcj;
    
    rule "Product price less than 500" // 给规则取个名
    when
        pp : Product( prePrice <= 500 ) // 规则
    then
        // 符合规则后执行的操作,是Java代码
        double prePrice = pp.getPrePrice();
        pp.setRealPrice(prePrice * 0.85);
        System.out.println(pp.getName() + "活动价是:" + pp.getRealPrice());
    end
    
    
    rule "Product price less than 1000" // 给规则取个名
    when
        p : Product( prePrice > 500 && prePrice <=1000 ) // 规则
    then
        // 符合规则后执行的操作,是Java代码
        double prePrice = p.getPrePrice();
        p.setRealPrice(prePrice * 0.8);
        System.out.println(p.getName() + "活动价是:" + p.getRealPrice());
    end
    
    
    rule "Product price more than 1000" // 给规则取个名
    when
        p : Product( prePrice > 1000 ) // 规则
    then
        // 符合规则后执行的操作,是Java代码
        double prePrice = p.getPrePrice();
        p.setRealPrice(prePrice - 300);
        System.out.println(p.getName() + "活动价是:" + p.getRealPrice());
    end
    

    4.编写配置文件

    运行 drools 需要一个固定的配置文件,在 resources 文件下的目录 META_INF,名称固定为 kmodule.xml

    配置文件至少包含如下几行:

    <kmodule xmlns="http://www.drools.org/xsd/kmodule">
        <kbase name="kbase1" packages="demo.rules">
            <ksession name="ksession1" />
        </kbase>
    </kmodule>
    

    配置简单说明:

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

    5.让规则文件程序跑起来

    Main.java 类中编写测试方法,让规则文件跑起来:

    package com.sharpcj;
    
    import org.kie.api.KieServices;
    import org.kie.api.runtime.KieContainer;
    import org.kie.api.runtime.KieSession;
    
    public class Main {
        public static void main(String[] args){
            new Main().test();
        }
    
        private void test(){
            // 构建KieServices
            KieServices ks = KieServices.Factory.get();
            KieContainer kc = ks.getKieClasspathContainer();
            // 获取kmodule.xml中配置中名称为ksession-rule的session,默认为有状态的。
            KieSession kSession = kc.newKieSession("ksession1");
    
            Product fan = new Product("电扇", 280);
            Product washer = new Product("洗衣机",2200);
            Product phone = new Product("手机", 998);
            kSession.insert(fan);
            kSession.insert(washer);
            kSession.insert(phone);
            kSession.fireAllRules();
            kSession.dispose();
        }
    }
    

    运行结果:

    三、其它说明

    1.不使用配置文件形式

    上面使用的配置文件形式加载 drools 文件是 drools 7.x 版本才有的,在此之前,我们通常使用代码形式加载规则文件,当然在 drools 7.x 中依然可以使用这种方式,只不过有些 API 已经过时了,或者更新了。下面用代码形式加载规则文件代码如下:

        /**
         * 不使用 drools 7.x 配置文件
         */
        private void test2(){
            KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
            kbuilder.add(ResourceFactory.newClassPathResource("demo/rules/product.drl"), ResourceType.DRL);
    
            KnowledgeBuilderErrors errors = kbuilder.getErrors();
            if (errors.size() > 0) {
                for (KnowledgeBuilderError error: errors) {
                    System.err.println(error);
                }
                throw new IllegalArgumentException("Could not parse knowledge.");
            }
    
    
            // 注释掉的是 drools 6.x API
            /*KnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
            kbase.addKnowledgePackages(kbuilder.getKnowledgePackages());
            StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();*/
    
            // drools 7.x API
            InternalKnowledgeBase kbase = KnowledgeBaseFactory.newKnowledgeBase();
            Collection<KiePackage> pkgs = kbuilder.getKnowledgePackages();
            kbase.addPackages(pkgs);
            KieSession kieSession = kbase.newKieSession();
            Product fan = new Product("电扇", 280);
            Product washer = new Product("洗衣机",2200);
            Product phone = new Product("手机", 998);
            kieSession.insert(fan);
            kieSession.insert(washer);
            kieSession.insert(phone);
            kieSession.fireAllRules();
            kieSession.dispose();
        }
    

    运行程序依然能得到相同的结果。

    2.规则文件的类型

    规则文件除了 drl 文件之类,还有其它类型的文件,如 xls, csv。

    四、附录

    Drools 官网首页: https://www.drools.org/
    Drools 官方文档: https://docs.jboss.org/drools/release/7.12.0.Final/drools-docs/html_single/index.html

  • 相关阅读:
    自定义提示框(alert、confirm 可自定义标题 内容 图标 取消按钮)
    Node.js 技術
    ASP.NET MVC+Spring.net+Nhibernate+EasyUI+Jquery开发案例(1)
    Memcached 命令简介
    MySQL 请选择合适的列
    WCF光芒下的Web Service
    如何实现共享软件网络授权认证,包括注册新用户、登录、修改密码等操作
    SOA面向服务架构简述
    Python Web 框架, 使用 Django 和 Python 开发 Web 站点
    Interface继承至System.Object?
  • 原文地址:https://www.cnblogs.com/joy99/p/10134893.html
Copyright © 2011-2022 走看看