前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Java规则引擎drools:drt动态生成规则并附上具体项目逻辑

Java规则引擎drools:drt动态生成规则并附上具体项目逻辑

作者头像
ydymz
发布2018-09-10 17:31:31
2.5K0
发布2018-09-10 17:31:31
举报
文章被收录于专栏:lgp20151222lgp20151222lgp20151222

一 整合

由于本人的码云太多太乱了,于是决定一个一个的整合到一个springboot项目里面。

附上自己的项目地址https://github.com/247292980/spring-boot

以整合功能

spring-boot,FusionChart,thymeleaf,vue,ShardingJdbc,mybatis-generator,微信分享授权,drools,spring-security,spring-jpa,webjars,Aspect

这次就来整合drools的动态生成规则(drt)。

二 开发目的

为什么写规则引擎要做到动态生成规则呢?

因为规则引擎的作用

一些多变的活动逻辑可以再不改变代码,不重新部署系统,如需求改需求,

一些通用但微变的逻辑,如人工智能的机器学习,达到ai修改数据库来微调自己的行为。

以上统称为 决策从逻辑剥离

真相就是上面的人不放心你,你要根据设计的mysql数据库写一个降智的后台系统给他们来决定什么时候发什么奖品。

三 项目设计

那么,很明显就是开发一个drools的规则引擎和一个有各种说明语言的,对一个数据库的表进行crud的后台操作系统。

drools这里做的很好,后者,drools就有一个workbench来给我们用了,我们还搞了中文版。

但是,什么东西一到了中国,就变味。

中国人看不懂drools的决策表,更不会根据workbench生成决策表。

于是,第一版drool的系统上线了之后,在需求的意见下,我们要搞个降智的后台操作系统。

而正如我之前博客所说,drools的官方文档很强,里面就有drt(动态规则模板)的例子,本质上就是workbench的劣化例子给我们看。

然后,再根据网上各处资源的魔改,我们给规则引擎升级成动态生成规则文件的,这也是我要拿来做例子的

四 代码讲解

我一直是代码即文档的伪支持者,所以大家吧项目clone下来观看更佳。

规则引擎其实就是规则的加载,规则的使用。(动态的规则引擎的规则加载,还要实现规则的生成。)

也就是loadRule和useRule。

loadRule

1.先从数据库获取规则 getActivityRuleList()

2.再跟据获取的规则生成drt可以解析的map型data prepareData(ruleDTO)

3.通过drt解析,生成drl规则string objectDataCompiler.compile(Arrays.asList(data), Thread.currentThread().getContextClassLoader().getResourceAsStream("give-reward-rule-template.drt"));

4.根据以上获得的规则string生成maven结构的规则并加载 createOrRefreshDrlInMemory(ruleDrls)

/**
 * 加载规则
 */

useRule

1.构建BaseFact  buildBaseFact(userId)

2.执行前,对BaseFact,uuid,RegisterMqDTO 进行操作 beforeExecute(orderId, fact, domain)

3.根据生成的RegisterFact执行规则匹配,并RuleExecutorResult为执行结果execute(registerFact, orderId)

    /**
     * 触发规则
     */
    public void useRule(String userId, String phone) {
        BaseFact fact = buildBaseFact(userId);
        /**
         * 因为是uuid所以修改了的规则,重载加载是新的drl,故从数据库动态加载之时,is_delete属性要注意
         * */
        String orderId = UUID.randomUUID().toString();
        /**
         * 此处应当是从其他服务获取的的消息体,而不是空值
         * */
        RegisterMqDTO domain = new RegisterMqDTO();
        domain.setTelephone(phone);
        try {
            /*可以知道一条信息,匹配了多少个规则,成功了几个*/
            RuleExecutorResult ruleExecutorResult = beforeExecute(orderId, fact, domain);
            log.info("RuleService|useRule|ruleExecutorResult={}", JSON.toJSON(ruleExecutorResult));
//            Assert.isTrue(ruleExecutorResult.getFailure() == 0, String.format("有%d条规则执行失败", ruleExecutorResult.getFailure()));
        } catch (Exception e) {
            log.error("RuleService|useRule|class={},orderId={}, userId={}, 规则执行异常:{}", this.getClass().getName(), orderId, "123456789", e.getMessage(), e);
        }
    }

五 结尾

其实说难不难,就是这个东西的思路想出来就有点难了。

其中,mq的设计和接入(由于是简单的demo所以也就没有写上),规则执行结果的反馈(虽然是我写的,但是个人感觉有点鸡肋),还有一些项目里面的逻辑,我也只是在demo里面提了几句并没有实现(诸如初始化项目跑一下loadRule的代码,我也没放),但是大致的框架都出来了,我们只要往里面填就可以了。sql语句,配置文件也在项目里面,有兴趣的自己跑跑即可。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-09-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一 整合
  • 二 开发目的
  • 三 项目设计
  • 四 代码讲解
    • loadRule
      • useRule
      • 五 结尾
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档