Drools集成SpringBootStarter

Drools集成SpringBootStarter

1.说明 基于fast-drools-spring-boot-starter, 能够方便的将规则引擎Drools集成到Spring Boot, 基于前面介绍过的文章Drools集成SpringBoot, 进一步改造成使用fast-drools-spring-boot-starter的项目。 2.fast-drools-spring-boot-starter 项目地址:Fast Drools 项...

1.说明

基于fast-drools-spring-boot-starter,
能够方便的将规则引擎Drools集成到Spring Boot,
基于前面介绍过的文章
Drools集成SpringBoot,
进一步改造成使用fast-drools-spring-boot-starter的项目。

2.fast-drools-spring-boot-starter

项目地址:
Fast Drools

项目特性:

  • SpringBoot与Drools快速整合,不需要配置繁琐的kmodule.xml,也不需要自己编写代码初始化Drools
  • 指定文件名执行评估规则,更加直观的流程分析
  • 规则文件动态加载
  • 规则文件分组控制
  • 使用NIO的文件映射,更快速的文件的读写
  • 基于缓存的规则文件控制,更高效的规则评估
  • 支持各种路径格式
  • 支持xls和xlsx格式的规则表文件
  • 日志监控流程中规则与评估对象的动态
  • 执行速度与性能的极致,且可定制

注意:
这是第三方个人开发的开源项目,
不推荐在正式项目中使用,
但是作者已经把jar包等发布到了阿里云的仓库,
所以国内的同学使用起来还是比较方便的。

3.创建Maven工程

pom.xml工程信息:

4.0.0com.ai.prddrools-fast-demo0.0.1-SNAPSHOTBased on fast-drools-spring-boot-starter, Drools integrats into the Spring Boot

4.引入Spring Boot相关依赖

引入spring-boot-starter-web作为Web工程,对外提供Rest服务,
引入spring-boot-starter-log4j2日志框架,打印测试匹配结果,
引入spring-boot-starter-test测试框架,开发Junt5测试用例:

2.3.1.RELEASEorg.springframework.bootspring-boot-dependencies${spring-boot.version}pomimportorg.springframework.bootspring-boot-starter-weborg.springframework.bootspring-boot-starter-loggingorg.springframework.bootspring-boot-starter-log4j2org.springframework.bootspring-boot-starter-testjunitjunitorg.junit.vintagejunit-vintage-engine

5.引入Drools相关依赖

引入fast-drools-spring-boot-starter即可:

8.0.7com.github.hongwen1993fast-drools-spring-boot-starter${fast.drools.version}

6.开发启动类

启动类DroolsApplication.java:

package com.ai.prd.drools;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DroolsApplication {
    public static void main(String[] args) {
        SpringApplication.run(DroolsApplication.class, args);
    }
}

7.操作对象Person

下面会对Person对象进行规则过滤,
这里给出定义Person.java:

package com.ai.prd.drools.entity;

public class Person {
    private String name;

    private int age;
}

8.开发规则文件

在src/main/resources/rules/com/ai/prd/目录下新建文件
ai-rules.drl:

package com.ai.prd
 
import com.ai.prd.drools.entity.Person;
import com.ai.prd.drools.action.PersonRuleAction;

// 根据名字匹配指定的人
rule "1.find target person"
    when
        $p : Person( name == "bob" )
    then
        PersonRuleAction.doParse($p, drools.getRule());
        System.out.println("Rule name is [" + drools.getRule().getName() + "]"); 
        System.out.println("Rule package is [" + drools.getRule().getPackageName() + "]");
end

// 根据年龄匹配找到打工人
rule "2.find the work person"
    when
        $p : Person( age >= 25 && age 

规则1匹配名字为bob的人,并且调用工具类PersonRuleAction打印相关日志,
同时打印规则的名称和包路径到控制台。
规则2匹配年龄在25到65之间的打工人,
然后把匹配到的人直接打印到控制台。

9.规则处理类

PersonRuleAction.java在匹配到相应规则时被调用,
此处仅实现日志打印的功能:

package com.ai.prd.drools.action;

import org.drools.core.definitions.rule.impl.RuleImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.ai.prd.drools.entity.Person;

/**
 * 触发Person相关的规则后的处理类
 */
public class PersonRuleAction {
    private static Logger LOG = LoggerFactory.getLogger(PersonRuleAction.class);

    // 目前只实现记录日志功能
    public static void doParse(Person person, RuleImpl rule) {
        LOG.debug("{} is matched Rule[{}]!", person, rule.getName());
    }
}

10.配置application.yml

在src/main/resources下新建application.yml:

server:
  port: 5117
  
# 指定规则文件文件夹,会自动扫描该目录下所有规则文件,决策表,以及CSV文件
spring:
  drools:
    path: classpath:rules/**/*.drl
    # 可以指定全局的mode,选择stream或cloud
    mode: stream
    # 指定规则文件自动更新的周期,单位秒,默认30秒扫描一次
    update: 10
    listener: on 

指定了应用运行的端口,
以及Drools相关的配置。

11.新建日志配置文件

在src/main/resources目录下,
新建日志配置文件Log4j2.xml:

日志文件配置后,
PersonRuleAction类打印的日志
不仅会输出到log/rule_result.log,
也会输出到控制台。

12.开发Junit5测试用例

针对上面规则文件中配置的规则,
开发两个Junit5的测试用例,
在src/test/java/目录下
创建DroolsApplicationTest.java:

package com.ai.prd.drools;

import static org.junit.jupiter.api.Assertions.assertEquals;

import org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.kie.api.runtime.KieSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import com.ai.prd.drools.entity.Address;
import com.ai.prd.drools.entity.Person;
import com.drools.core.KieTemplate;

@SpringBootTest
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class DroolsApplicationTest {

    @Autowired
    private KieTemplate kieTemplate;

    private KieSession kSession;

    @BeforeAll
    public void initKieSession() {
        // 每次测试都要重新获取kSession
        // 同时可以指定要加载的规则文件
        kSession = kieTemplate.getKieSession("ai-rules.drl");
    }

    @AfterAll
    public void runDispose() {
        // 全部测试用例执行完毕后,需要手动释放资源
        kSession.dispose();
    }

    @Test
    public void test1findTargetPerson() {
        Person bob = new Person();
        bob.setName("bob");
        kSession.insert(bob);

        Person other = new Person();
        other.setName("other1");
        kSession.insert(other);

        int rules = kSession.fireAllRules();
        // 按照规则1只有bob能够匹配上
        assertEquals(1, rules);
    }

    @Test
    public void test2findWorkPerson() {
        Person bob = new Person();
        bob.setAge(33);
        kSession.insert(bob);

        Person other = new Person();
        other.setAge(88);
        kSession.insert(other);

        int rules = kSession.fireAllRules();
        assertEquals(1, rules);
    }

注意这里的KieTemplate是fast-drools-spring-boot-starter提供的,
而不是以前kie-spring提供的KieContainer了。

13.运行测试用例

DroolsApplicationTest执行后,
控制台输出:

15:46:02.441 [main] INFO  com.ai.prd.drools.DroolsApplicationTest - Starting DroolsApplicationTest on yuwen-asiainfo with PID 3836 (started by yuwen in D:CodeWorkdroolsdrools-demosdrools-fast-demo)
15:46:02.443 [main] INFO  com.ai.prd.drools.DroolsApplicationTest - No active profile set, falling back to default profiles: default
15:46:03.387 [main] INFO  org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Initializing ExecutorService 'applicationTaskExecutor'
15:46:03.701 [main] INFO  com.ai.prd.drools.DroolsApplicationTest - Started DroolsApplicationTest in 1.524 seconds (JVM running for 2.704)
15:46:04.081 [main] WARN  org.drools.compiler.kie.builder.impl.KieBuilderImpl - File 'file0.drl' is in folder '' but declares package 'com.ai.prd'. It is advised to have a correspondance between package and folder names.
15:46:04.911 [main] WARN  org.drools.compiler.kie.builder.impl.KieBuilderImpl - File 'file0.drl' is in folder '' but declares package 'com.ai.prd'. It is advised to have a correspondance between package and folder names.
15:46:05.723 [main] DEBUG com.ai.prd.drools.action.PersonRuleAction - Person [name=bob, birthDay=null, age=0, address=null] is matched Rule[1.find target person]!
Rule name is [1.find target person]
Rule package is [com.ai.prd]
Person [name=null, birthDay=null, age=33, address=null] is a work person!
15:46:05.748 [SpringContextShutdownHook] INFO  org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor - Shutting down ExecutorService 'applicationTaskExecutor'
0

评论0

鱼翔浅底,鹰击长空,驼走大漠
没有账号? 注册  忘记密码?