Drools简单使用
2023-04-01 本文已影响0人
Nick_4438
drools是什么
Drools 是一个开源的业务规则管理系统 (BRMS) 和决策管理系统 (DMS),它提供了一个基于规则引擎的方法来管理和执行业务规则和决策。
Drools 允许用户定义、管理和执行规则,它提供了一种基于声明式语言的方式来表达业务规则和决策,这使得规则和决策更加易于理解和维护。Drools 可以与 Java 应用程序集成,也可以作为独立的服务运行。Drools 还提供了一些高级功能,如事务处理、事件处理和实时决策等。
使用 Drools 可以帮助企业更加灵活地管理和调整业务规则和决策,以快速适应不断变化的业务需求。
简单使用例子
该例子在网上找的,整理时未找到出处,如果哪位发现了告知我一下
实现一个商品打折的规则,买1件不打折,买2件打98折,买3件打0.85折
代码如下:
- 创建文件夹
mkdir my-project
cd my-project
mkdir -p src/main/java/com/example
mkdir -p src/main/resources
- 初始化
pom.xml
文件
<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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>my-project</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>my-project</name>
<url>http://maven.apache.org</url>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-bom</artifactId>
<type>pom</type>
<version>7.69.0.Final</version>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.3</version>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-compiler</artifactId>
</dependency>
<dependency>
<groupId>org.drools</groupId>
<artifactId>drools-mvel</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Maven Compiler Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>11</source>
<target>11</target>
</configuration>
</plugin>
<!-- Maven Surefire Plugin -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>3.0.0-M5</version>
</plugin>
</plugins>
</build>
</project>
- 初始化
META-INF/kmodule.xml
,定义drools元数据信息
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<!--
kbase 可以存在多个
name: 指定kbase的名字,需要是唯一的
packages: 包名,可以理解为到src/main/resources目录下查找这个包名下的规则文件,多个包使用逗号分割
default: 当前kbase是否是默认的kbase
-->
<kbase name="shop-kabse" packages="com.example.shop" default="false">
<!--
ksession 可以存在多个
name: 指定ksession 的名字,需要唯一
defalut: 当前ksession在这个kbase下是否是默认的
type: 指定当前ksession是否是有状态的 stateless表示是无状态的
-->
<ksession name="shop-ksession" default="false" type="stateless"/>
<ksession name="shop-ksession-stateful" default="false" type="stateful"/>
</kbase>
</kmodule>
shop-ksession和shop-ksession-stateful将在调用
StatelessKieSession kieSession = kieContainer.newStatelessKieSession("shop-ksession");
时使用
-
com/example/shop/shop-discount.drl
,定义drools文件
// 包名,必须防止到第一行,这个名字需要和 kbase中package属性的值一致
package com.example.shop
/**
* 导入类
*/
import com.example.CustomerOrder
// 定义规则
rule "shop-rule-01"
when
// 模式匹配:到工作内存中查找CustomerOrder,并且这个对象的purchaseQuantity值需要是1,
// 如果条件成立,$order是绑定变量名,一般以$开头,和fact对象区分开
$order:CustomerOrder(purchaseQuantity == 1)
then
System.out.println("匹配规则 shop-rule-01");
// 赋值,此处赋值后,在Java代码中获取获取到赋值后的值
$order.setDiscount(1D);
end
rule "shop-rule-02"
when
$order:CustomerOrder(purchaseQuantity == 2)
then
System.out.println("匹配规则 shop-rule-02");
$order.setDiscount(0.98);
end
rule "shop-rule-03"
when
$order:CustomerOrder(purchaseQuantity >= 3)
then
System.out.println("匹配规则 shop-rule-03");
$order.setDiscount(0.85);
end
- 初始化领域对象
com/example/CustomerOrder.java
package com.example;
public class CustomerOrder {
/**
* 购买了几件衣服
*/
private Integer purchaseQuantity;
/**
* 最终打多少折
*/
private Double discount;
public CustomerOrder(Integer purchaseQuantity) {
this.purchaseQuantity = purchaseQuantity;
}
public Integer getPurchaseQuantity() {
return purchaseQuantity;
}
public void setPurchaseQuantity(Integer purchaseQuantity) {
this.purchaseQuantity = purchaseQuantity;
}
public Double getDiscount() {
return discount;
}
public void setDiscount(Double discount) {
this.discount = discount;
}
}
- 准备调用文件
com/example/App.java
package com.example;
import org.kie.api.KieServices;
import org.kie.api.event.rule.DebugRuleRuntimeEventListener;
import org.kie.api.runtime.KieContainer;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.StatelessKieSession;
/**
* Hello world!
*/
public class App {
public static void main(String[] args) {
// 无状态session测试
statelessSessionTest();
// 有状态session测试
statefulSessionTest();
}
private static void statelessSessionTest() {
// 获取kie services
KieServices kieServices = KieServices.get();
// 获取kie容器对象
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 获取kie session , 此处获取的是无状态的session,因为 <ksession name="shop-ksession" default="false" type="stateless"/>
// 中type="stateless"就是无状态的session
StatelessKieSession kieSession = kieContainer.newStatelessKieSession("shop-ksession");
// 创建一个对象,可以理解为 Fact对象,即事实对象
CustomerOrder customerOrder = new CustomerOrder(2);
// 添加监听器,便于观察日志
kieSession.addEventListener(new DebugRuleRuntimeEventListener());
// 无状态的session只需要执行 execute 方法即可。
kieSession.execute(customerOrder);
System.err.println("通过规则后,获取到的折扣为:" + customerOrder.getDiscount());
}
private static void statefulSessionTest() {
// 获取kie services
KieServices kieServices = KieServices.get();
// 获取kie容器对象
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 获取kie session , 此处获取的是有状态的session
KieSession kieSession = kieContainer.newKieSession("shop-ksession-stateful");
// 创建一个对象,可以理解为 Fact对象,即事实对象
CustomerOrder customerOrder = new CustomerOrder(3);
// 添加监听器,便于观察日志
kieSession.addEventListener(new DebugRuleRuntimeEventListener());
// 将customerOrder对象加入到工作内存中
kieSession.insert(customerOrder);
// 触发所有的规则,如果只想触发指定的规则,则使用fireAllRules(AgendaFilter agendaFilter)方法
kieSession.fireAllRules();
// 有状态的session一定需要调用dispose方法
kieSession.dispose();
System.err.println("通过规则后,获取到的折扣为:" + customerOrder.getDiscount());
}
}
- 执行效果
11:03:39.746 [main] DEBUG org.kie.api.internal.utils.ServiceDiscoveryImpl - Service org.kie.api.internal.weaver.KieWeavers is implemented by org.kie.internal.services.KieWeaversImpl@3967e60c
11:03:39.836 [main] INFO org.drools.compiler.kie.builder.impl.ClasspathKieProject - Found kmodule: file:/E:/nick/drools/my-project/target/classes/META-INF/kmodule.xml
11:03:39.839 [main] DEBUG org.drools.compiler.kie.builder.impl.ClasspathKieProject - KieModule URL type=file url=/E:/nick/drools/my-project/target/classes
11:03:39.993 [main] WARN org.drools.compiler.kie.builder.impl.ClasspathKieProject - Unable to find pom.properties in /E:/nick/drools/my-project/target/classes
11:03:39.996 [main] INFO org.drools.compiler.kie.builder.impl.ClasspathKieProject - Recursed up folders, found and used pom.xml E:\nick\drools\my-project\pom.xml
11:03:39.997 [main] INFO org.drools.compiler.kie.builder.impl.InternalKieModuleProvider - Creating KieModule for artifact com.example:my-project:1.0-SNAPSHOT
11:03:39.998 [main] DEBUG org.drools.compiler.kie.builder.impl.ClasspathKieProject - Discovered classpath module com.example:my-project:1.0-SNAPSHOT
11:03:39.999 [main] DEBUG org.drools.compiler.kie.builder.impl.KieRepositoryImpl - KieModule was added: FileKieModule[releaseId=com.example:my-project:1.0-SNAPSHOT,file=E:\nick\drools\my-project\target\classes]
11:03:40.000 [main] INFO org.drools.compiler.kie.builder.impl.KieContainerImpl - Start creation of KieBase: shop-kabse
11:03:40.008 [main] DEBUG org.drools.compiler.compiler.JavaDialectConfiguration - Selected compiler ECLIPSE [drools.dialect.java.compiler:null, hasEclipseCompiler:true]
11:03:40.030 [main] DEBUG org.drools.compiler.compiler.JavaDialectConfiguration - Selected compiler ECLIPSE [drools.dialect.java.compiler:null, hasEclipseCompiler:true]
11:03:40.030 [main] DEBUG org.drools.compiler.compiler.JavaDialectConfiguration - Selected compiler ECLIPSE [drools.dialect.java.compiler:null, hasEclipseCompiler:true]
11:03:40.368 [main] INFO org.drools.compiler.kie.builder.impl.KieContainerImpl - End creation of KieBase: shop-kabse
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:1:1875532039:1875532039:1:DEFAULT:NON_TRAIT:com.example.CustomerOrder:com.example.CustomerOrder@6fca5907], getObject()=com.example.CustomerOrder@6fca5907, getKnowledgeRuntime()=KieSession[0], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:1:1875532039:1875532039:1:DEFAULT:NON_TRAIT:com.example.CustomerOrder:com.example.CustomerOrder@6fca5907], originOffset=-1, propagationNumber=2, rule=null, type=INSERTION]]
11:03:40.387 [main] DEBUG org.drools.core.common.DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
匹配规则 shop-rule-02
11:03:40.398 [main] DEBUG org.drools.core.common.DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
11:03:40.398 [main] DEBUG org.drools.core.common.DefaultAgenda - State was HALTING is now INACTIVE
11:03:40.398 [main] DEBUG org.drools.core.common.DefaultAgenda - State was INACTIVE is now DISPOSED
11:03:40.401 [main] DEBUG org.drools.core.common.DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
匹配规则 shop-rule-03
11:03:40.401 [main] DEBUG org.drools.core.common.DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
11:03:40.401 [main] DEBUG org.drools.core.common.DefaultAgenda - State was HALTING is now INACTIVE
11:03:40.401 [main] DEBUG org.drools.core.common.DefaultAgenda - State was INACTIVE is now DISPOSED
通过规则后,获取到的折扣为:0.98
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:1:609825180:609825180:1:DEFAULT:NON_TRAIT:com.example.CustomerOrder:com.example.CustomerOrder@2459319c], getObject()=com.example.CustomerOrder@2459319c, getKnowledgeRuntime()=KieSession[1], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:1:609825180:609825180:1:DEFAULT:NON_TRAIT:com.example.CustomerOrder:com.example.CustomerOrder@2459319c], originOffset=-1, propagationNumber=2, rule=null, type=INSERTION]]
通过规则后,获取到的折扣为:0.85
Process finished with exit code 0
处理多个数据
这一个按钮处理一个list对象,本例子从内存内读取对象列表,理论上该对象数据可以从数据库中获取。
- 添加规则文件
com/example/retire/retire-rules.drl
// 包名,必须防止到第一行,这个名字需要和 kbase中package属性的值一致
package com.example.retire
/**
* 导入类
*/
import com.example.Person
// 定义规则
rule "retire-rule-01"
when
// 模式匹配:到工作内存中查找Person,并且这个对象的家里需要有矿
// 如果条件成立,$person,一般以$开头,和fact对象区分开
$person:Person(hasMine == true)
then
System.out.println($person.getName()+":你家里有矿,快快退休");
// 赋值,此处赋值后,在Java代码中获取获取到赋值后的值
$person.setRetire(true);
end
rule "retire-rule-02"
when //家里没矿,又小于65岁,那老实工作吧
$person:Person(hasMine == false, age < 65 )
then
System.out.println($person.getName()+":家里穷,再干几年吧");
$person.setRetire(false);
end
rule "retire-rule-03"
when //家里没矿,又大于等于65岁,没办法,干不动了,退休吧
$person:Person(hasMine == false, age >= 65 )
then
System.out.println($person.getName()+":年纪到了,牛都干不动了,退了退了");
$person.setRetire(true);
end
- 修改元数据文件
META-INF/kmodule.xml
,添加retire-kabse
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<!--
kbase 可以存在多个
name: 指定kbase的名字,需要是唯一的
packages: 包名,可以理解为到src/main/resources目录下查找这个包名下的规则文件,多个包使用逗号分割
default: 当前kbase是否是默认的kbase
-->
<kbase name="shop-kabse" packages="com.example.shop" default="false">
<!--
ksession 可以存在多个
name: 指定ksession 的名字,需要唯一
defalut: 当前ksession在这个kbase下是否是默认的
type: 指定当前ksession是否是有状态的 stateless表示是无状态的
-->
<ksession name="shop-ksession" default="false" type="stateless"/>
<ksession name="shop-ksession-stateful" default="false" type="stateful"/>
</kbase>
<kbase name="retire-kabse" packages="com.example.retire" default="false">
<ksession name="retire-ksession" default="false" type="stateless"/>
<ksession name="retire-ksession-stateful" default="false" type="stateful"/>
</kbase>
</kmodule>
- 添加Person待处理对象
package com.example;
public class Person {
private String name;
private Integer age;
private Boolean hasMine;
private Boolean retire;
public Person() {
}
public Person(String name, Integer age, Boolean hasMine) {
this.name = name;
this.age = age;
this.hasMine = hasMine;
}
public Boolean getRetire() {
return retire;
}
public void setRetire(Boolean retire) {
this.retire = retire;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Boolean getHasMine() {
return hasMine;
}
public void setHasMine(Boolean hasMine) {
this.hasMine = hasMine;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", hasMine=" + hasMine +
", retire=" + retire +
'}';
}
}
- 调用规则例子
private static void handlePersonTest(){
// 获取kie services
KieServices kieServices = KieServices.get();
// 获取kie容器对象
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 获取kie session , 此处获取的是有状态的session
KieSession kieSession = kieContainer.newKieSession("retire-ksession-stateful");
List<Person> persons = Arrays.asList(
new Person("张三",25,true),
new Person("李四",62,false),
new Person("李四",66,false)
);;
// 添加监听器,便于观察日志
kieSession.addEventListener(new DebugRuleRuntimeEventListener());
// 将读取的数据插入到规则引擎中
for (Person person : persons) {
kieSession.insert(person);
}
// 触发所有的规则,如果只想触发指定的规则,则使用fireAllRules(AgendaFilter agendaFilter)方法
kieSession.fireAllRules();
// 有状态的session一定需要调用dispose方法
kieSession.dispose();
for (Person person : persons) {
System.err.println(person.toString());
}
}
- 执行日志
10:56:46.502 [main] INFO org.drools.compiler.kie.builder.impl.ClasspathKieProject - Found kmodule: file:/E:/nick/drools/my-project/target/classes/META-INF/kmodule.xml
10:56:46.505 [main] DEBUG org.drools.compiler.kie.builder.impl.ClasspathKieProject - KieModule URL type=file url=/E:/nick/drools/my-project/target/classes
10:56:46.653 [main] WARN org.drools.compiler.kie.builder.impl.ClasspathKieProject - Unable to find pom.properties in /E:/nick/drools/my-project/target/classes
10:56:46.656 [main] INFO org.drools.compiler.kie.builder.impl.ClasspathKieProject - Recursed up folders, found and used pom.xml E:\nick\drools\my-project\pom.xml
10:56:46.657 [main] INFO org.drools.compiler.kie.builder.impl.InternalKieModuleProvider - Creating KieModule for artifact com.example:my-project:1.0-SNAPSHOT
10:56:46.658 [main] DEBUG org.drools.compiler.kie.builder.impl.ClasspathKieProject - Discovered classpath module com.example:my-project:1.0-SNAPSHOT
10:56:46.659 [main] DEBUG org.drools.compiler.kie.builder.impl.KieRepositoryImpl - KieModule was added: FileKieModule[releaseId=com.example:my-project:1.0-SNAPSHOT,file=E:\nick\drools\my-project\target\classes]
10:56:46.660 [main] INFO org.drools.compiler.kie.builder.impl.KieContainerImpl - Start creation of KieBase: retire-kabse
10:56:46.669 [main] DEBUG org.drools.compiler.compiler.JavaDialectConfiguration - Selected compiler ECLIPSE [drools.dialect.java.compiler:null, hasEclipseCompiler:true]
10:56:46.690 [main] DEBUG org.drools.compiler.compiler.JavaDialectConfiguration - Selected compiler ECLIPSE [drools.dialect.java.compiler:null, hasEclipseCompiler:true]
10:56:46.690 [main] DEBUG org.drools.compiler.compiler.JavaDialectConfiguration - Selected compiler ECLIPSE [drools.dialect.java.compiler:null, hasEclipseCompiler:true]
10:56:47.034 [main] INFO org.drools.compiler.kie.builder.impl.KieContainerImpl - End creation of KieBase: retire-kabse
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:1:992955027:992955027:1:DEFAULT:NON_TRAIT:com.example.Person:Person{name='张三', age=25, hasMine=true, retire=null}], getObject()=Person{name='张三', age=25, hasMine=true, retire=null}, getKnowledgeRuntime()=KieSession[0], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:1:992955027:992955027:1:DEFAULT:NON_TRAIT:com.example.Person:Person{name='张三', age=25, hasMine=true, retire=null}], originOffset=-1, propagationNumber=2, rule=null, type=INSERTION]]
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:2:1092822:1092822:2:DEFAULT:NON_TRAIT:com.example.Person:Person{name='李四', age=62, hasMine=false, retire=null}], getObject()=Person{name='李四', age=62, hasMine=false, retire=null}, getKnowledgeRuntime()=KieSession[0], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:2:1092822:1092822:2:DEFAULT:NON_TRAIT:com.example.Person:Person{name='李四', age=62, hasMine=false, retire=null}], originOffset=-1, propagationNumber=3, rule=null, type=INSERTION]]
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:3:1641931089:1641931089:3:DEFAULT:NON_TRAIT:com.example.Person:Person{name='李四', age=66, hasMine=false, retire=null}], getObject()=Person{name='李四', age=66, hasMine=false, retire=null}, getKnowledgeRuntime()=KieSession[0], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:3:1641931089:1641931089:3:DEFAULT:NON_TRAIT:com.example.Person:Person{name='李四', age=66, hasMine=false, retire=null}], originOffset=-1, propagationNumber=4, rule=null, type=INSERTION]]
Person{name='张三', age=25, hasMine=true, retire=true}
Person{name='李四', age=62, hasMine=false, retire=false}
Person{name='李四', age=66, hasMine=false, retire=true}
10:56:47.059 [main] DEBUG org.drools.core.common.DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
张三:你家里有矿,快快退休
李四:家里穷,再干几年吧
李四:年纪到了,牛都干不动了,退了退了
10:56:47.073 [main] DEBUG org.drools.core.common.DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
10:56:47.073 [main] DEBUG org.drools.core.common.DefaultAgenda - State was HALTING is now INACTIVE
10:56:47.073 [main] DEBUG org.drools.core.common.DefaultAgenda - State was INACTIVE is now DISPOSED
Process finished with exit code 0
全集变量
前面一个版本,实现退休年龄是写死的,如果想要作一个参数传入,则做如下修改:
- 添加规则文件
com/example/retire1/retire-rules.drl
// 包名,必须防止到第一行,这个名字需要和 kbase中package属性的值一致
package com.example.retire1;
/**
* 导入类
*/
import com.example.Person;
global com.example.MyGlobalObject myGlobalObject;
//定义全局参数
//global Integer count; //定义一个包装类型的全局变量
// 定义规则
rule "retire1-rule-01"
when
// 模式匹配:到工作内存中查找Person,并且这个对象的家里需要有矿
// 如果条件成立,$person,一般以$开头,和fact对象区分开
$person:Person(hasMine == true)
then
System.out.println($person.getName()+":你家里有矿,快快退休:");
// System.out.println(count);
// 赋值,此处赋值后,在Java代码中获取获取到赋值后的值
$person.setRetire(true);
end
rule "retire1-rule-02"
when //家里没矿,又小于65岁,那老实工作吧
$person:Person(hasMine == false, age < myGlobalObject.getRetireAge() )
then
System.out.println($person.getName()+":家里穷,再干几年吧,还没超过"+myGlobalObject.getRetireAge());
$person.setRetire(false);
end
rule "retire1-rule-03"
when //家里没矿,又大于等于65岁,没办法,干不动了,退休吧
$person:Person(hasMine == false, age >= myGlobalObject.getRetireAge() )
then
System.out.println($person.getName()+":年纪到了,牛都干不动了,退了退了,超过"+myGlobalObject.getRetireAge());
$person.setRetire(true);
end
- 添加规则元数据声明
META-INF/kmodule.xml
<kmodule xmlns="http://www.drools.org/xsd/kmodule">
<!--
kbase 可以存在多个
name: 指定kbase的名字,需要是唯一的
packages: 包名,可以理解为到src/main/resources目录下查找这个包名下的规则文件,多个包使用逗号分割
default: 当前kbase是否是默认的kbase
-->
<kbase name="shop-kabse" packages="com.example.shop" default="false">
<!--
ksession 可以存在多个
name: 指定ksession 的名字,需要唯一
defalut: 当前ksession在这个kbase下是否是默认的
type: 指定当前ksession是否是有状态的 stateless表示是无状态的
-->
<ksession name="shop-ksession" default="false" type="stateless"/>
<ksession name="shop-ksession-stateful" default="false" type="stateful"/>
</kbase>
<kbase name="retire-kabse" packages="com.example.retire" default="false">
<ksession name="retire-ksession" default="false" type="stateless"/>
<ksession name="retire-ksession-stateful" default="false" type="stateful"/>
</kbase>
<kbase name="retire-kabse1" packages="com.example.retire1" default="false">
<ksession name="retire-ksession1" default="false" type="stateless"/>
<ksession name="retire-ksession-stateful1" default="false" type="stateful"/>
</kbase>
</kmodule>
- 添加全局对象
com/example/MyGlobalObject.java
package com.example;
public class MyGlobalObject {
private Integer retireAge;
public MyGlobalObject(Integer retireAge) {
this.retireAge = retireAge;
}
public Integer getRetireAge() {
return retireAge;
}
public void setRetireAge(Integer retireAge) {
this.retireAge = retireAge;
}
}
- 调用规则例子
src/main/java/com/example/App.java
public static void main(String[] args) {
handlePersonTest1();
}
private static void handlePersonTest1(){
// 获取kie services
KieServices kieServices = KieServices.get();
// 获取kie容器对象
KieContainer kieContainer = kieServices.getKieClasspathContainer();
// 获取kie session , 此处获取的是有状态的session
KieSession kieSession = kieContainer.newKieSession("retire-ksession-stateful1");
// 定义全局参数
MyGlobalObject myGlobalObject = new MyGlobalObject(60);
// 将全局参数插入到规则引擎中
kieSession.setGlobal("myGlobalObject", myGlobalObject);
List<Person> persons = Arrays.asList(
new Person("张三",25,true),
new Person("李四",55,false),
new Person("王五",62,false),
new Person("李麻子",66,false)
);;
// 添加监听器,便于观察日志
kieSession.addEventListener(new DebugRuleRuntimeEventListener());
// 将读取的数据插入到规则引擎中
for (Person person : persons) {
kieSession.insert(person);
}
// 触发所有的规则,如果只想触发指定的规则,则使用fireAllRules(AgendaFilter agendaFilter)方法
kieSession.fireAllRules();
// 有状态的session一定需要调用dispose方法
kieSession.dispose();
for (Person person : persons) {
System.err.println(person.toString());
}
}
- 执行效果日志:
12:00:51.599 [main] INFO org.drools.compiler.kie.builder.impl.ClasspathKieProject - Found kmodule: file:/E:/nick/drools/my-project/target/classes/META-INF/kmodule.xml
12:00:51.602 [main] DEBUG org.drools.compiler.kie.builder.impl.ClasspathKieProject - KieModule URL type=file url=/E:/nick/drools/my-project/target/classes
12:00:51.755 [main] WARN org.drools.compiler.kie.builder.impl.ClasspathKieProject - Unable to find pom.properties in /E:/nick/drools/my-project/target/classes
12:00:51.758 [main] INFO org.drools.compiler.kie.builder.impl.ClasspathKieProject - Recursed up folders, found and used pom.xml E:\nick\drools\my-project\pom.xml
12:00:51.758 [main] INFO org.drools.compiler.kie.builder.impl.InternalKieModuleProvider - Creating KieModule for artifact com.example:my-project:1.0-SNAPSHOT
12:00:51.759 [main] DEBUG org.drools.compiler.kie.builder.impl.ClasspathKieProject - Discovered classpath module com.example:my-project:1.0-SNAPSHOT
12:00:51.761 [main] DEBUG org.drools.compiler.kie.builder.impl.KieRepositoryImpl - KieModule was added: FileKieModule[releaseId=com.example:my-project:1.0-SNAPSHOT,file=E:\nick\drools\my-project\target\classes]
12:00:51.762 [main] INFO org.drools.compiler.kie.builder.impl.KieContainerImpl - Start creation of KieBase: retire-kabse1
12:00:51.771 [main] DEBUG org.drools.compiler.compiler.JavaDialectConfiguration - Selected compiler ECLIPSE [drools.dialect.java.compiler:null, hasEclipseCompiler:true]
12:00:51.791 [main] DEBUG org.drools.compiler.compiler.JavaDialectConfiguration - Selected compiler ECLIPSE [drools.dialect.java.compiler:null, hasEclipseCompiler:true]
12:00:51.791 [main] DEBUG org.drools.compiler.compiler.JavaDialectConfiguration - Selected compiler ECLIPSE [drools.dialect.java.compiler:null, hasEclipseCompiler:true]
12:00:52.145 [main] INFO org.drools.compiler.kie.builder.impl.KieContainerImpl - End creation of KieBase: retire-kabse1
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:1:1833343025:1833343025:1:DEFAULT:NON_TRAIT:com.example.Person:Person{name='张三', age=25, hasMine=true, retire=null}], getObject()=Person{name='张三', age=25, hasMine=true, retire=null}, getKnowledgeRuntime()=KieSession[0], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:1:1833343025:1833343025:1:DEFAULT:NON_TRAIT:com.example.Person:Person{name='张三', age=25, hasMine=true, retire=null}], originOffset=-1, propagationNumber=2, rule=null, type=INSERTION]]
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:2:1022830989:1022830989:2:DEFAULT:NON_TRAIT:com.example.Person:Person{name='李四', age=55, hasMine=false, retire=null}], getObject()=Person{name='李四', age=55, hasMine=false, retire=null}, getKnowledgeRuntime()=KieSession[0], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:2:1022830989:1022830989:2:DEFAULT:NON_TRAIT:com.example.Person:Person{name='李四', age=55, hasMine=false, retire=null}], originOffset=-1, propagationNumber=3, rule=null, type=INSERTION]]
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:3:33510911:33510911:3:DEFAULT:NON_TRAIT:com.example.Person:Person{name='王五', age=62, hasMine=false, retire=null}], getObject()=Person{name='王五', age=62, hasMine=false, retire=null}, getKnowledgeRuntime()=KieSession[0], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:3:33510911:33510911:3:DEFAULT:NON_TRAIT:com.example.Person:Person{name='王五', age=62, hasMine=false, retire=null}], originOffset=-1, propagationNumber=4, rule=null, type=INSERTION]]
==>[ObjectInsertedEventImpl: getFactHandle()=[fact 0:4:891232836:891232836:4:DEFAULT:NON_TRAIT:com.example.Person:Person{name='李麻子', age=66, hasMine=false, retire=null}], getObject()=Person{name='李麻子', age=66, hasMine=false, retire=null}, getKnowledgeRuntime()=KieSession[0], getPropagationContext()=PhreakPropagationContext [entryPoint=EntryPoint::DEFAULT, factHandle=[fact 0:4:891232836:891232836:4:DEFAULT:NON_TRAIT:com.example.Person:Person{name='李麻子', age=66, hasMine=false, retire=null}], originOffset=-1, propagationNumber=5, rule=null, type=INSERTION]]
12:00:52.171 [main] DEBUG org.drools.core.common.DefaultAgenda - State was INACTIVE is now FIRING_ALL_RULES
张三:你家里有矿,快快退休:
李四:家里穷,再干几年吧,还没超过60
王五:年纪到了,牛都干不动了,退了退了,超过60
李麻子:年纪到了,牛都干不动了,退了退了,超过60
12:00:52.186 [main] DEBUG org.drools.core.common.DefaultAgenda - State was FIRING_ALL_RULES is now HALTING
12:00:52.186 [main] DEBUG org.drools.core.common.DefaultAgenda - State was HALTING is now INACTIVE
12:00:52.186 [main] DEBUG org.drools.core.common.DefaultAgenda - State was INACTIVE is now DISPOSED
Person{name='张三', age=25, hasMine=true, retire=true}
Person{name='李四', age=55, hasMine=false, retire=false}
Person{name='王五', age=62, hasMine=false, retire=true}
Person{name='李麻子', age=66, hasMine=false, retire=true}
Process finished with exit code 0