规则引擎Drools
首先简单了解什么是规则引擎:
Drools是JBoss组织提供的开源规则引擎,主要用于Java应用程序中的规则管理,就是将业务规则从程序中抽离出来,业务规则改变后不需要重启服务。
Drools是一个基于RETE算法的规则引擎,支持动态规则扩展和维护,可以根据需要添加、删除或修改规则。它允许用户使用声明方式表达业务逻辑,将规则与业务代码解耦,使得规则的变化不需要修改代码,只需在规则文件中进行修改即可23。此外,Drools支持基于规则的访问和操作数据的功能,如过滤、排序、检索等。
drools规则引擎由以下三部分构成:
-
Working Memory(工作内存)
-
Rule Base(规则库)
-
Inference Engine(推理引擎)
Inference Engine推理引擎又包括:
-
Pattern Matcher(匹配器) 具体匹配哪一个规则,由这个完成
-
Agenda(议程)
-
Execution Engine(执行引擎)
规则体相关的一些关键字
rule:关键字,表示规则开始,参数为规则的唯一名称。
attributes:规则属性,是rule与when之间的参数,为可选项。
when:关键字,后面跟规则的条件部分。
LHS(Left Hand Side):是规则的条件部分的通用名称。它由零个或多个条件元素组成。如果LHS为空,则它将被视为始终为true的条件元素。 (左手边)
then:关键字,后面跟规则的结果部分。
RHS(Right Hand Side):是规则的后果或行动部分的通用名称。 (右手边)
end:关键字,表示一个规则结束。
规则文件组成
- package:包名,只限于逻辑上的管理,同一个包名下的查询或者函数可以直接调用
- import:用于导入类或静态方法
- global:全局变量
- fuanction:自定义函数
- query:查询
- rule end:规则体
1.创建一个spring boot项目,第一步导依赖
<properties>
<java.version>17</java.version>
<drools.version>8.41.0.Final</drools.version>
</properties>
<dependencies>
<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>
2.创建一个配置类config,规则文件路径的文件要与下面创建的drl文件名相同
/**
* 规则引擎配置类
*/
@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();
KieContainer kieContainer = kieServices.newKieContainer(kieModule.getReleaseId());
return kieContainer;
}
}
3.创建一个实体类
public class Order {
private double amout;
private double score;
public double getAmout() {
return amout;
}
public void setAmout(double amout) {
this.amout = amout;
}
public double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
4.创建一个drl文件,主要这边的属性是需要通过 import 引入实体类才能使用路径根据自己的来
//订单积分规则
package com.atguigu.drools.order
import com.aiguigu.drools_demo.bean.Order
//规则一: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
5.创建一个测试类测试一下是否正确
@Autowired
private KieContainer kieContainer;
@Test
public void test(){
//从Kie容器对象中获取会话对象
KieSession session = kieContainer.newKieSession();
//Fact对象,事实对象
Order order = new Order();
order.setAmout(10000);
//将Order对象插入到工作内存中
session.insert(order);
//激活规则,由Drools框架自动进行规则匹配,如果规则匹配成功,则执行当前规则
session.fireAllRules();
//关闭会话
session.dispose();
System.out.println("订单金额:" + order.getAmout() +
",添加积分:" + order.getScore());
}