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

整体项目结构



上图是基于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

后语

此系列课程持续更新中,QQ群:593177274(可扫描左上侧栏目二维码),欢迎大家加入讨论。点击链接关注《Drools博客专栏》。由于Drools资料较少,教程编写不易,每篇博客都亲身实践编写demo。如果对你有帮助也欢迎赞赏(微信)! 也是对原创的最大支持!

《Drools7.0.0.Final规则引擎教程》Springboot+规则重新加载的更多相关文章

  1. Android4.0图库Gallery2代码分析(二) 数据管理和数据加载

    Android4.0图库Gallery2代码分析(二) 数据管理和数据加载 2012-09-07 11:19 8152人阅读 评论(12) 收藏 举报 代码分析android相册优化工作 Androi ...

  2. SpringBoot是如何加载配置文件的?

    前言 本文针对版本2.2.0.RELEASE来分析SpringBoot的配置处理源码,通过查看SpringBoot的源码来弄清楚一些常见的问题比如: SpringBoot从哪里开始加载配置文件? Sp ...

  3. esri-leaflet入门教程(4)-加载各类图层

    esri-leaflet入门教程(4)-加载各类图层 by 李远祥 在leaflet中图层一般分为底图(Basemap)和叠加图层(Overlay).前面章节已经介绍过底图其实也是实现了TileLay ...

  4. SpringBoot启动如何加载application.yml配置文件

    一.前言 在spring时代配置文件的加载都是通过web.xml配置加载的(Servlet3.0之前),可能配置方式有所不同,但是大多数都是通过指定路径的文件名的形式去告诉spring该加载哪个文件: ...

  5. SpringBoot 配置的加载

    SpringBoot 配置的加载 SpringBoot配置及环境变量的加载提供许多便利的方式,接下来一起来学习一下吧! 本章内容的源码按实战过程采用小步提交,可以按提交的节点一步一步来学习,仓库地址: ...

  6. SpringBoot配置文件的加载位置

    1.springboot启动会扫描以下位置的application.properties或者application.yml文件作为SpringBoot的默认配置文件 --file:/config/ - ...

  7. springboot 配置文件的加载顺序

    springboot 配置文件的加载顺序1.在命令行中传入的参数.2. SPRING APPLICATION JSON中的属性. SPRING_APPLICATION—JSON是以JSON格式配置在系 ...

  8. 《Drools7.0.0.Final规则引擎教程》第3章 3.1 Hello World 实例

    3.1 Hello World 实例 在上一章中介绍了Drools5x版本中规则引擎使用的实例,很明显在Drools7中KnowledgeBase类已经标注为"@Deprecated&quo ...

  9. 《Drools7.0.0.Final规则引擎教程》第2章 追溯Drools5的使用

    2.1 Drools5简述 上面已经提到Drools是通过规则编译.规则收集和规则的执行来实现具体功能的.Drools5提供了以下主要实现API: KnowledgeBuilder Knowledge ...

随机推荐

  1. 20145310 《Java程序设计》第8周学习总结

    20145310 <Java程序设计>第8周学习总结 教材学习内容总结 本周主要进行第十四章和第十五章的学习. 第十四章 NIO使用频道(channel)来衔接数据节点,对数据区的标记提供 ...

  2. 关于JavaScript对象,你所不知道的事(一)- 先谈对象

    这篇博文的主要目的是为了填坑,很久之前我发表了一篇名为关于JavaScript对象中的一切(一) - 对象属性的文章,想要谈一谈JavaScript对象,可那时只是贴了一张关于这个主题的思维导图,今天 ...

  3. 【前端】vue.js实现输入框绑定

    vue.js实现输入框绑定 实现效果如下: 实现代码及注释 <!DOCTYPE html> <html> <head> <title>vue.js数据动 ...

  4. [BZOJ2282]消防

    Description 某个国家有n个城市,这n个城市中任意两个都连通且有唯一一条路径,每条连通两个城市的道路的长度为zi(zi<=1000). 这个国家的人对火焰有超越宇宙的热情,所以这个国家 ...

  5. dp_c_区间dp_g

    You Are The One 题意:有n个人准备按顺序上台,上台前有个小黑屋(先进后出,即栈),可以被安排进去等待,也可以直接上台,一个人一旦被安排进去,后面的人就可以先上台(小黑屋无限大).每个人 ...

  6. Flume在企业大数据仓库架构中位置及功能

    Flume在企业大数据仓库架构中位置及功能 hadoop 数据仓库 flume 数据仓库架构 1.如下图所示,外部数据中,关系型数据库导入到HDFS用sqoop,由Nginx产生的文件实时监控用Flu ...

  7. codeforces796E Exam Cheating

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000 作者博客:http://www.cnblogs.com/ljh2000-jump/ ...

  8. session判断重复提交

    import javax.servlet.http.HttpServletRequest; /** * @author: jiang * @Date: 2019/2/19 09:37 * @Descr ...

  9. Log4j 2.0 使用说明(1) 之HelloWorld

    以下是Log4j2.0的类图,以便大家对2.0有一个整体的理解. 就如我们学习任何一个技术一样,这里我们首先写一个Hello World: 1,新建工程TestLog4j 2,下载Log4j 2.0有 ...

  10. 简单UML

    http://www.cnblogs.com/pluviophile/p/7542017.html,看了这篇博文感觉这个例子有用遂搬运过来方便查阅 上面的类图就体现了所需要了解的类的6个基本关系 该类 ...