《Drools7.0.0.Final规则引擎教程》Springboot+规则重新加载

简介: 《Drools7.0.0.Final规则引擎教程》Springboot+规则重新加载

在《Drools7.0.0.Final规则引擎教程》之Springboot集成中介绍了怎样将Drools与Springboot进行集成,本篇博客介绍一下集成之后,如何实现从数据库读取规则并重新加载规则的简单demo。因本章重点介绍的是Drools相关操作的API,所以将查询数据库部分的操作省略,直接使用数据库查询出的规则代码来进行规则的重新加载。另外,此示例采用访问一个http请求来进行重新加载,根据实际需要可考虑定时任务进行加载等扩展方式。最终的使用还是要结合具体业务场景来进行分析扩展。


整体项目结构


image.png上图是基于intellij maven的项目结构。其中涉及到springboot的Drools集成配置类,重新加载规则类。一些实体类和工具类。下面会抽出比较重要的类进行分析说明。

DroolsAutoConfiguration

@Configuration
public class DroolsAutoConfiguration {
    private static final String RULES_PATH = "rules/";
    @Bean
    @ConditionalOnMissingBean(KieFileSystem.class)
    public KieFileSystem kieFileSystem() throws IOException {
        KieFileSystem kieFileSystem = getKieServices().newKieFileSystem();
        for (Resource file : getRuleFiles()) {
            kieFileSystem.write(ResourceFactory.newClassPathResource(RULES_PATH + file.getFilename(), "UTF-8"));
        }
        return kieFileSystem;
    }
    private Resource[] getRuleFiles() throws IOException {
        ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
        return resourcePatternResolver.getResources("classpath*:" + RULES_PATH + "**/*.*");
    }
    @Bean
    @ConditionalOnMissingBean(KieContainer.class)
    public KieContainer kieContainer() throws IOException {
        final KieRepository kieRepository = getKieServices().getRepository();
        kieRepository.addKieModule(new KieModule() {
            public ReleaseId getReleaseId() {
                return kieRepository.getDefaultReleaseId();
            }
        });
        KieBuilder kieBuilder = getKieServices().newKieBuilder(kieFileSystem());
        kieBuilder.buildAll();
        KieContainer kieContainer = getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());
        KieUtils.setKieContainer(kieContainer);
        return getKieServices().newKieContainer(kieRepository.getDefaultReleaseId());
    }
    private KieServices getKieServices() {
        return KieServices.Factory.get();
    }
    @Bean
    @ConditionalOnMissingBean(KieBase.class)
    public KieBase kieBase() throws IOException {
        return kieContainer().getKieBase();
    }
    @Bean
    @ConditionalOnMissingBean(KieSession.class)
    public KieSession kieSession() throws IOException {
        KieSession kieSession = kieContainer().newKieSession();
        KieUtils.setKieSession(kieSession);
        return kieSession;
    }
    @Bean
    @ConditionalOnMissingBean(KModuleBeanFactoryPostProcessor.class)
    public KModuleBeanFactoryPostProcessor kiePostProcessor() {
        return new KModuleBeanFactoryPostProcessor();
    }
}

此类主要用来初始化Drools的配置,其中需要注意的是对KieContainer和KieSession的初始化之后都将其设置到KieUtils类中。

KieUtils

KieUtils类中存储了对应的静态方法和静态属性,供其他使用的地方获取和更新。

public class KieUtils {
    private static KieContainer kieContainer;
    private static KieSession kieSession;
    public static KieContainer getKieContainer() {
        return kieContainer;
    }
    public static void setKieContainer(KieContainer kieContainer) {
        KieUtils.kieContainer = kieContainer;
        kieSession = kieContainer.newKieSession();
    }
    public static KieSession getKieSession() {
        return kieSession;
    }
    public static void setKieSession(KieSession kieSession) {
        KieUtils.kieSession = kieSession;
    }
}

ReloadDroolsRules

提供了reload规则的方法,也是本篇博客的重点之一,其中从数据库读取的规则代码直接用字符串代替,读者可自行进行替换为数据库操作。

@Service
public class ReloadDroolsRules {
    public void reload() throws UnsupportedEncodingException {
        KieServices kieServices = KieServices.Factory.get();
        KieFileSystem kfs = kieServices.newKieFileSystem();
        kfs.write("src/main/resources/rules/temp.drl", loadRules());
        KieBuilder kieBuilder = kieServices.newKieBuilder(kfs).buildAll();
        Results results = kieBuilder.getResults();
        if (results.hasMessages(Message.Level.ERROR)) {
            System.out.println(results.getMessages());
            throw new IllegalStateException("### errors ###");
        }
        KieUtils.setKieContainer(kieServices.newKieContainer(getKieServices().getRepository().getDefaultReleaseId()));
        System.out.println("新规则重载成功");
    }
    private String loadRules() {
        // 从数据库加载的规则
        return "package plausibcheck.adress\n\n import com.neo.drools.model.Address;\n import com.neo.drools.model.fact.AddressCheckResult;\n\n rule \"Postcode 6 numbers\"\n\n    when\n  then\n        System.out.println(\"规则2中打印日志:校验通过!\");\n end";
    }
    private KieServices getKieServices() {
        return KieServices.Factory.get();
    }
}

TestController

提供了验证入口和reload入口。

@RequestMapping("/test")
@Controller
public class TestController {
    @Resource
    private ReloadDroolsRules rules;
    @ResponseBody
    @RequestMapping("/address")
    public void test(){
        KieSession kieSession = KieUtils.getKieSession();
        Address address = new Address();
        address.setPostcode("994251");
        AddressCheckResult result = new AddressCheckResult();
        kieSession.insert(address);
        kieSession.insert(result);
        int ruleFiredCount = kieSession.fireAllRules();
        System.out.println("触发了" + ruleFiredCount + "条规则");
        if(result.isPostCodeResult()){
            System.out.println("规则校验通过");
        }
    }
    @ResponseBody
    @RequestMapping("/reload")
    public String reload() throws IOException {
        rules.reload();
        return "ok";
    }
}

其他

其他类和文件内容参考springboot集成部分或demo源代码。


操作步骤如下:启动项目访问http://localhost:8080/test/address 会首先触发默认加载的address.drl中的规则。当调用reload之后,再次调用次方法会发现触发的规则已经变成重新加载的规则了。


CSDN demo下载地址:http://download.csdn.net/detail/wo541075754/9918297

GitHub demo下载地址:https://github.com/secbr/drools/tree/master/springboot-drools-reload-rules


目录
相关文章
|
6月前
|
JavaScript 前端开发 Java
SpringBoot之静态资源规则与定制化
SpringBoot之静态资源规则与定制化
134 1
|
6月前
|
XML Java 数据格式
SpringBoot中yaml格式、语法规则及数据读取方式(3种)
SpringBoot中yaml格式、语法规则及数据读取方式(3种)
657 0
|
6月前
|
前端开发 JavaScript Java
Springboot 使用thymeleaf 服务器无法加载resources中的静态资源异常处理
Springboot 使用thymeleaf 服务器无法加载resources中的静态资源异常处理
508 0
|
1月前
|
架构师 Java 开发者
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
在40岁老架构师尼恩的读者交流群中,近期多位读者成功获得了知名互联网企业的面试机会,如得物、阿里、滴滴等。然而,面对“Spring Boot自动装配机制”等核心面试题,部分读者因准备不足而未能顺利通过。为此,尼恩团队将系统化梳理和总结这一主题,帮助大家全面提升技术水平,让面试官“爱到不能自已”。
得物面试:Springboot自动装配机制是什么?如何控制一个bean 是否加载,使用什么注解?
|
21天前
|
JavaScript 前端开发 Java
SpringBoot_web开发-webjars&静态资源映射规则
https://www.91chuli.com/ 举例:jquery前端框架
16 0
|
1月前
|
Java Shell C++
Springboot加载注入bean的方式
本文详细介绍了Spring Boot中Bean的装配方法。首先讲解了使用@Component、@Service、@Controller、@Repository等注解声明Bean的方式,并解释了这些注解之间的关系及各自适用的层次。接着介绍了通过@Configuration和@Bean注解定义Bean的方法,展示了其灵活性和定制能力。最后讨论了@Component与@Bean的区别,并提供了在Spring Boot应用中装配依赖包中Bean的三种方法:使用@ComponentScan注解扫描指定包、使用@Import注解导入特定Bean以及在spring.factories文件中配置Bean。
|
2月前
|
消息中间件 NoSQL 安全
(转)Spring Boot加载 不同位置的 application.properties配置文件顺序规则
这篇文章介绍了Spring Boot加载配置文件的顺序规则,包括不同位置的application.properties文件的加载优先级,以及如何通过命令行参数或环境变量来指定配置文件的名称和位置。
|
3月前
|
Java Spring
Spring boot +Thymeleaf 本地图片加载失败(图片路径)的问题及解决方法
这篇文章详细讲解了在Spring Boot应用程序中本地图片无法加载的问题原因,并提供了两个示例来说明如何通过使用正确的相对路径或Thymeleaf语法来解决图片路径问题。
|
3月前
|
前端开发 JavaScript Java
Spring boot 本地图片不能加载(图片路径)的问题及解决方法
这篇文章讨论了Spring Boot应用程序中本地图片无法加载的问题,通常由图片路径不正确引起,并提供了使用正确的相对路径和Thymeleaf语法来解决这一问题的两种方法。
|
3月前
|
Java 测试技术 Spring
Java SpringBoot 加载 yml 配置文件中字典项
Java SpringBoot 加载 yml 配置文件中字典项
44 0