浅浅学习Spring下Drools规则引擎使用

背景

近期偶然看到一个介绍了Drools规则引擎的视频。之前在上家公司也接触过一点点,场景主要是配合工作流引擎使用,用于在特定节点判断该由谁负责审批。

规则引擎在业务研发中使用频率还是比较高的,尤其是面对复杂、需灵活变更的场景更加适合。所以趁着还算热乎,赶紧再熟悉一小下。

Drools--java语言开发的开源业务规则引擎

DROOLS(JBOSS RULES )具有一个易于访问企业策略、易于调整以及易于管理的开源业务规则引擎,符合业内标准,速度快、效率高。业务分析师或审核人员可以利用它轻松查看业务规则,从而检验是否已编码的规则执行了所需的业务规则。(www.drools.org.cn/

入门

步骤1: 引入依赖

xml 复制代码
<!-- Drools依赖 -->
<dependency>
  <groupId>org.kie</groupId>
  <artifactId>kie-api</artifactId>
  <version>7.61.0.Final</version>
</dependency>
<dependency>
  <groupId>org.kie</groupId>
  <artifactId>kie-spring</artifactId>
  <version>7.61.0.Final</version>
</dependency>
<dependency>
  <groupId>org.drools</groupId>
  <artifactId>drools-core</artifactId>
  <version>7.61.0.Final</version>
</dependency>

步骤2:增加kieContainer配置

KieContainer是Drools规则引擎的容器,它用于加载和管理规则文件。

通过KieContainer,我们可以获取到规则文件中定义的规则和规则集,并创建相应的KieSession对象。

KieContainer通常在应用程序启动时创建,并在整个应用程序的生命周期中重复使用。

java 复制代码
@Bean
public KieContainer kieContainer() {
    KieServices kieServices = KieServices.get();
    KieFileSystem kieFileSystem = kieServices.newKieFileSystem();
    // 配置规则文件所在路径 /src/main/resources/myrules/rules.drl
    kieFileSystem.write(ResourceFactory.newClassPathResource("myrules/rules.drl"));
    KieBuilder kieBuilder = kieServices.newKieBuilder(kieFileSystem).buildAll();
    KieModule kieModule = kieBuilder.getKieModule();
    return kieServices.newKieContainer(kieModule.getReleaseId());
}

步骤3: 编写规则文件drl

更加复杂的编写规则可参考: www.drools.org.cn/161.html 这里可以通过全局变量global的方式将SpringBean注入到规则文件中使用。

java 复制代码
package myrules;
import com.rules.engine.DroolsTestService
import com..Person;

// 注入Spring管理的Bean
global com.rules.engine.DroolsTestService myService;

rule "Adult Rule"
    when
        // 将规则赋值给$person变量
        $person : Person()
        // 当参数中的age >=18时,进入then处理
        Person(age >= 18)
    then
        // 调用Spring管理的Service处理
        myService.elderThan18($person);
        System.out.println("The person is an adult");
end

rule "Teenager Rule"
    when
         // 将规则赋值给$person变量
        $person : Person()
        // 当参数中的age <18时,进入then处理
        Person(age < 18)
    then
            // 调用Spring管理的Service处理
        myService.youngerThan18($person);
        System.out.println("The person is a teenager");
end

步骤4: 规则触发

这里核心是基于kieSession触发规则。

KieSession是Drools规则引擎的执行环境,它用于执行规则。在KieSession中,我们可以插入事实(Person),并调用规则引擎来匹配规则并执行匹配的规则。

KieSession提供了多种执行规则的方法,例如fireAllRules()用于执行所有匹配的规则。KieSession通常在需要执行规则的时候创建,并在执行完规则后关闭。

也就是说,KieContainer用于加载和管理规则文件,而KieSession则提供了规则的执行环境,用于插入事实并执行规则。通过这两个对象的配合使用,我们可以实现规则的加载、管理和执行。

java 复制代码
@Service
@Slf4j
public class DroolsService {
    @Autowired
    private KieContainer kieContainer;

    /**
     * 规则中需要使用的SpringBean
     */
    @Autowired
    private DroolsTestService droolsTestService;

    /**
     * 该方法用于将给定的Person对象应用到Drools规则中,并触发规则的执行。
     * @param person
     */
    public void applyRules(Person person) {
        // 创建一个KieSession
        KieSession kieSession = kieContainer.newKieSession();
        try {
            // 通过设置全局变量到规则文件中去
            kieSession.setGlobal("myService", droolsTestService);
            // 添加规则运行时事件监听器,用于调试
            kieSession.addEventListener(new DebugRuleRuntimeEventListener());
            kieSession.addEventListener(new DebugAgendaEventListener());
            // 将变量插入到规则中
            kieSession.insert(person);
            // 触发规则
            kieSession.fireAllRules();
        } catch (Exception e) {
            log.error("applyRules error", e);
        } finally {
            kieSession.dispose();
        }
    }
}

步骤5: 验证一下

规则使用使用到的Service 代码

java 复制代码
@Service
@Slf4j
public class DroolsTestService {

    public void youngerThan18(Person person) {
        person.setName(person.getName() + "<----> youngerThan18");
    }

    public void elderThan18(Person person) {
        person.setName(person.getName() + "<----> elderThan18");
    }
}

触发使用的controller

java 复制代码
@RestController
@RequestMapping(value = "/ruleEngine")
public class RuleEngineController {

    @Autowired
    private DroolsService droolsService;
    
    @PostMapping("/test")
    public Person test(@RequestBody Person person) {
        droolsService.applyRules(person);
        return person;
    }
}

可以通过日志判断规则的执行情况,可以看到规则是命中了adult规则,并且也执行到了我们的Service中。 Adult规则测试:

Teenager规则测试:

符合预期。 如果想了解更多,更加详细的介绍请可以移步该文juejin.cn/post/709946...

相关推荐
leobertlan2 小时前
2025年终总结
前端·后端·程序员
面向Google编程2 小时前
从零学习Kafka:数据存储
后端·kafka
易安说AI3 小时前
Claude Opus 4.6 凌晨发布,我体验了一整晚,说说真实感受。
后端
易安说AI3 小时前
Ralph Loop 让Claude无止尽干活的牛马...
前端·后端
易安说AI3 小时前
用 Claude Code 远程分析生产日志,追踪 Claude Max 账户被封原因
后端
JH30734 小时前
SpringBoot 优雅处理金额格式化:拦截器+自定义注解方案
java·spring boot·spring
颜酱4 小时前
图结构完全解析:从基础概念到遍历实现
javascript·后端·算法
Coder_Boy_5 小时前
技术让开发更轻松的底层矛盾
java·大数据·数据库·人工智能·深度学习
invicinble5 小时前
对tomcat的提供的功能与底层拓扑结构与实现机制的理解
java·tomcat
较真的菜鸟5 小时前
使用ASM和agent监控属性变化
java