规则引擎Drools的介绍和使用

一. 概述

Drools是一款基于Java的开源规则引擎,将规则与业务代码解耦。规则以脚本的形式存储在一个文件中,使规则的变化不需要修改代码,重新启动机器即可在线上环境中生效。

规则引擎实现了业务决策从应用程序代码中分离出来,并使用预定义的语义模块编写业务决策。接受数据输入、解释业务规则,以及基于业务规则做出业务决策,从而提供极大的编程便利。

  • 规则引擎核心思想:将应用程序中的业务决策部分分离出来

  • 使得业务规则的变更不需要修改项目代码、重启服务器就可以在线上环境立即生效

适用场景

Drools规则引擎可以应用于许多不同的场景,以下是一些常见的使用场景:

  1. 业务规则管理:Drools可以帮助组织和管理大量的业务规则,从而提高业务规则的可维护性和灵活性。
  2. 金融风控:Drools可以帮助金融机构自动化执行风险评估和合规性检查,以确保符合监管要求。
  3. 电子商务:Drools可以帮助电子商务网站根据客户的行为和偏好自动化推荐产品。
  4. 物流管理:Drools可以帮助物流公司根据货物类型、目的地和运输方式自动化计算运费和路线。
  5. 游戏开发:Drools可以帮助游戏开发人员自动化处理游戏规则和事件。

二. 快速开发

1> 创建SpringBoot工程

2> 引入Drools相关依赖

 <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <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-mvel</artifactId>
            <version>${drools.version}</version>
        </dependency>
    </dependencies>

 3> 创建Drools配置类DroolsConfig

package com.nianxi.drools_demo.config;

import org.kie.api.KieServices;
import org.kie.api.builder.*;
import org.kie.api.runtime.KieContainer;
import org.kie.internal.io.ResourceFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * 规则引擎配置类
 */
@Configuration
public class DroolsConfig {

    private static final KieServices kieServices = KieServices.Factory.get();
    //制定规则文件的路径
    private static final String RULES_CUSTOMER_RULES_DRL = "rules/order.drl";

    @Bean
    public KieContainer kieContainer() {
        //获得Kie容器对象
        KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
        kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_CUSTOMER_RULES_DRL));

        KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem);
        kieBuilder.buildAll();

        KieModule kieModule = kieBuilder.getKieModule();

        return kieServices.newKieContainer(kieModule.getReleaseId());
    }

}

4> 创建实体类Order

package com.nianxi.drools_demo.model;

/**
 * @author Jie.
 * @description: TODO
 * @date 2024/7/13
 * @version: 1.0
 */
public class Order {

    private double amount;
    private double score;

    public double getAmount() {
        return amount;
    }

    public void setAmount(double amount) {
        this.amount = amount;
    }

    public double getScore() {
        return score;
    }

    public void setScore(double score) {
        this.score = score;
    }
}

5> 创建规则文件order.drl(注意安装Drools插件)

//订单积分规则
package com.nianxi.drools_demo.order
import com.nianxi.drools_demo.model.Order

global com.nianxi.drools_demo.model.Integral integral;


//规则一:100元以下 不加分
rule "order_rule_1"
    when
        $order:Order(amout < 100)
    then
        $order.setScore(0);
        System.out.println("成功匹配到规则一:100元以下 不加分");
end

//规则二:100元 - 500元 加100分
rule "order_rule_2"
    when
        $order:Order(amout >= 100 && amout < 500)
    then
         $order.setScore(100);
         System.out.println("成功匹配到规则二:100元 - 500元 加100分");
end

//规则三:500元 - 1000元 加500分
rule "order_rule_3"
    when
        $order:Order(amout >= 500 && amout < 1000)
    then
         $order.setScore(500);
         System.out.println("成功匹配到规则三:500元 - 1000元 加500分");
end

//规则四:1000元以上 加1000分
rule "order_rule_4"
    when
        $order:Order(amout >= 1000)
    then
         $order.setScore(1000);
         System.out.println("成功匹配到规则四:1000元以上 加1000分");
end

6> 测试

package com.nianxi.drools_demo;

import com.nianxi.drools_demo.model.Integral;
import com.nianxi.drools_demo.model.Order;
import com.nianxi.drools_demo.model.Order1;
import org.junit.jupiter.api.Test;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@SpringBootTest
public class DroolsDemosApplicationTests {

    @Autowired
    private KieContainer kieContainer;

    @Test
    public void test(){
        //从Kie容器对象中获取会话对象
        KieSession session = kieContainer.newKieSession();

        //Fact对象,事实对象
        Order order = new Order();
        order.setAmout(300);

        //将Order对象插入到工作内存中
        session.insert(order);

        //激活规则,由Drools框架自动进行规则匹配,如果规则匹配成功,则执行当前规则
        session.fireAllRules();
        //关闭会话
        session.dispose();

        System.out.println("订单金额:" + order.getAmout() +
                ",添加积分:" + order.getScore());
    }
}

 

 三.详细介绍

drools规则引擎由以下三部分构成:

  • Working Memory(工作内存)

  • Rule Base(规则库)

  • Inference Engine(推理引擎)

其中Inference Engine(推理引擎)又包括:

  • Pattern Matcher(匹配器) 具体匹配哪一个规则,由这个完成

  • Agenda(议程)

  • Execution Engine(执行引擎)

四. Drools基础语法

1. 规则文件组成

       在使用Drools时非常重要的一个工作就是编写规则文件,通常规则文件的后缀为.drl

 

2. 规则体语法结构

规则体语法结构 开始位置 rule,结束位置 end

//结构组成
rule "ruleName"
    attributes
    when
        LHS 
    then
        RHS
end

rule:关键字,表示规则开始,参数为规则的唯一名称。

attributes:规则属性,是rule与when之间的参数,为可选项。

when:关键字,后面跟规则的条件部分。

LHS(Left Hand Side):是规则的条件部分的通用名称。它由零个或多个条件元素组成。如果LHS为空,则它将被视为始终为true的条件元素。 (左手边)

then:关键字,后面跟规则的结果部分。

RHS(Right Hand Side):是规则的后果或行动部分的通用名称。 (右手边)

end:关键字,表示一个规则结束。

3. 模式匹配

rule "rule_1"
	when
		$order:Order(amout >100 && amout < 500)
	then
		$order.setScore(100);
		 System.out.println("成功匹配到规则二:100元 - 500元 加100分");
end

 4. Drools内置方法

        Drools提供了一些方法可以用来操作工作内存中的数据,操作完成后规则引擎会重新进行相关规则的匹配,原来没有匹配成功的规则在我们修改数据完成后有可能就会匹配成功了。

 1> 修改 update方法

update方法的作用是更新工作内存中的数据,并 让相关的规则重新匹配。

参数:

//Fact对象,事实对象
Order order = new Order();
order.setAmout(30);

规则:

rule "order_rule_1"
	when
		$order:Order(amout < 100)
	then
		$order.setAmout(150);
		update($order)
		System.out.println("成功匹配到规则一:100元以下 不加分");
end

rule "order_rule_2"
	when
		$order:Order(amout >= 100 && amout < 500)
	then
		$order.setScore(100);
		System.out.println("成功匹配到规则二:100元 - 500元 加100分");
end

测试会输出俩条成功匹配到一和二的输出信息,积分为100

2> 添加 insert方法

insert方法的作用是向工作内存中插入数据,并让相关的规则重新匹配

rule "order_rule_1"
	when
		$order:Order(amout < 100)
	then
		Order order = new Order();
		order.setAmout(150);
		insert(order);
		System.out.println("成功匹配到规则一:100元以下 不加分");
end

rule "order_rule_2"
	when
		$order:Order(amout >= 100 && amout < 500)
	then
		$order.setScore(100);
		System.out.println("成功匹配到规则二:100元 - 500元 加100分");
end

最后会输出俩条规则,但是积分为0

3> 删除 retract方法

retract方法的作用是删除工作内存中的数据,并让相关的规则重新匹配。

//规则二:100元 - 500元 加100分
rule "order_rule_2"
    salience 3
    when
        $order:Order(amount >= 100 && amount < 500)
    then
//         retract($order);
         $order.setScore(100);
         System.out.println("成功匹配到规则二:100元 - 500元 加100分");
end

结果为匹配到规则二,积分为0

5. Drools规则属性

1> salience属性
  • salience属性用于指定规则的执行优先级,取值类型为Integer数值越大越优先执行

  • 没有添加执行优先级,执行由上到下执行
//规则一:100元以下 不加分
rule "order_rule_1"
    when
        $order:Order(amount < 100)
    then
        $order.setScore(0);
        System.out.println("成功匹配到规则一:100元以下 不加分");
end

//规则二:100元 - 500元 加100分
rule "order_rule_2"
    when
        $order:Order(amount >= 100 && amount < 500)
    then
         $order.setScore(100);
         System.out.println("成功匹配到规则二:100元 - 500元 加100分");
end

//规则三:500元 - 1000元 加500分
rule "order_rule_3"
    when
        $order:Order(amount >= 500 && amount < 1000)
    then
         $order.setScore(500);
         System.out.println("成功匹配到规则三:500元 - 1000元 加500分");
end

//规则四:1000元以上 加1000分
rule "order_rule_4"
    when
        $order:Order(amount >= 1000 && amount < 5000)
    then
         $order.setScore(1000);
         System.out.println("成功匹配到规则四:1000元 - 5000元 加1000分");
end

//规则五:5000元以上 加5000分
rule "order_rule_5"
     when
         $order:Order(amount>=5000)
     then
         retract($order)
         System.out.println("成功匹配到规则五:5000元以上 加5000分");
end
  • 添加优先级
//规则一:100元以下 不加分
rule "order_rule_1"
    salience 1
    when
        $order:Order(amount < 100)
    then

        $order.setScore(0);
        System.out.println("成功匹配到规则一:100元以下 不加分");
end

//规则二:100元 - 500元 加100分
rule "order_rule_2"
    salience 3
    when
        $order:Order(amount >= 100 && amount < 500)
    then
//         retract($order);
         $order.setScore(100);
         System.out.println("成功匹配到规则二:100元 - 500元 加100分");
end

//规则三:500元 - 1000元 加500分
rule "order_rule_3"
    salience 2
    when
        $order:Order(amount >= 500 && amount < 1000)
    then
         $order.setScore(500);
         System.out.println("成功匹配到规则三:500元 - 1000元 加500分");
end

//规则四:1000元以上 加1000分
rule "order_rule_4"
    salience 4
    when
        $order:Order(amount >= 1000 && amount < 5000)
    then
         $order.setScore(1000);
         System.out.println("成功匹配到规则四:1000元 - 5000元 加1000分");
end

//规则五:5000元以上 加5000分
rule "order_rule_5"
    salience 5
     when
         $order:Order(amount>=5000)
     then
         retract($order)
         System.out.println("成功匹配到规则五:5000元以上 加5000分");
end
2> no-loop属性
  • no-loop属性用于防止死循环

//订单积分规则
package com.order
import com.atguigu.drools.model.Order

//规则一:100元以下 不加分
rule "order_rule_1"
    no-loop true         //防止陷入死循环
    when
        $order:Order(amout < 100)
    then
        $order.setScore(0);
        update($order)
        System.out.println("成功匹配到规则一:100元以下 不加分");
end

6. Drools高级语法

  • global关键字用于在规则文件中定义全局变量,它可以让应用程序的对象在规则文件中能够被访问。

  • 语法结构为:global 对象类型 对象名称

//订单积分规则
package com.order
import com.atguigu.drools.bean.Order1

global com.atguigu.drools.bean.Integral integral;

//规则一:100元以下 不加分
rule "order_rule_1"
    no-loop true         //防止陷入死循环
    when
        $order:Order1(amout < 100)
    then
        integral.setScore(10);
        update($order)
        System.out.println("成功匹配到规则一:100元以下 不加分");
end

测试

@SpringBootTest
public class DroolsDemosApplicationTests {

    @Autowired
    private KieContainer kieContainer;

    @Test
    public void test(){
        //从Kie容器对象中获取会话对象
        KieSession session = kieContainer.newKieSession();

        //Fact对象,事实对象
        Order1 order = new Order1();
        order.setAmout(30);

        //全局变量
        Integral integral = new Integral();
        session.setGlobal("integral",integral);

        //将Order对象插入到工作内存中
        session.insert(order);

        //激活规则,由Drools框架自动进行规则匹配,如果规则匹配成功,则执行当前规则
        session.fireAllRules();
        //关闭会话
        session.dispose();

        System.out.println("订单金额:" + order.getAmout() +
                ",添加积分:" + integral.getScore());
    }
}

四. 总结

Drools是一种规则引擎,它允许用户通过定义规则来管理和执行业务规则。主要功能和作用包括:

  1. 规则管理:Drools提供了一个规则编辑器和存储库,允许用户定义和管理业务规则。用户可以使用规则编辑器创建规则,并将它们保存在规则库中进行集中管理。这样可以方便地修改、更新和删除规则。

  2. 规则评估:Drools允许用户将规则与传入的数据进行匹配和评估。用户可以通过定义规则的条件和动作来描述规则的行为。当传入的数据满足规则的条件时,规则引擎将执行规则的动作。

  3. 决策支持:Drools可以帮助用户进行决策支持,通过评估和执行规则来生成决策结果。用户可以定义一组规则来描述不同的决策情况,并根据传入的数据来决定执行哪个规则。

  4. 业务流程管理:Drools还提供了一种业务流程管理的功能,允许用户定义和管理业务流程。用户可以使用规则来定义业务流程的各个步骤和条件,并根据传入的数据来执行相应的流程步骤。

        总的来说,Drools可以帮助用户管理和执行业务规则,提供决策支持和业务流程管理的功能,使业务逻辑更加灵活和可配置。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晚睡早起₍˄·͈༝·͈˄*₎◞ ̑̑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值