Skip to content
Hale-Lee edited this page May 16, 2022 · 8 revisions

花了一个多月的时间,总算把这个模块完成了,想想还是开源了吧。 想法来源于工作的压力,在紧张的开发周期中需要完成一个40多项的规则检查,然后大量的数据调用都在数据库中的,特别是一些黑白名单的数据,基本上也就是在这个地方使用一次,和其他业务数据没有重复使用的可能,如果要完成这么不常用表的数据的mybatis bean,dao 之类的工作,也是需要花不少时间的吧。何况在系统中看到这么多只是使用一次的entity文件,总是觉得别扭。

在调查分析了Drools, Visual Rule等框架之后,还是决定自己写一个引擎吧。

所谓的规则引擎,其实就是if-then的结构了,if中就是各种判断条件,或者其组合(LHS),我们只要理顺这个组合条件就可以了,与其他的框架一样,我们也设置的rule的优先级,为了兼容Drools的框架, 我这里也设置了数字大的优先级更高。 同时,针对各个业务规则之间的逻辑组合关系,我定义了Group的概念,同一个Group的rule必须要有一个parent的Rule,Rule中可以通过GroupExpress来定义rule之间的逻辑运算关系(&&,||, !),还可以通过括号将这个逻辑关系组合起来,这样就扩展规则的关联性。

针对于数据库中不存在的业务规则,比如调用外部的数据接口,或需要从其他service获取数据的情况,因为这些业务数据来源不统一,我干脆就设计了独立的java 类,只要继承了AbstractRuleItem类,实现了doCheck方法就可以了。

在then的执行逻辑(RHS)中,简单的实现AbstractCommand接口就可以了,业务实现的逻辑千差万别,所执行的动作也各不相同,因此这里也做了虚拟化了。同时,考虑大多数时候,都需要写一个执行日志,因此又增加了一个AbstractResultLogRecorder接口,这是一个register/manager的结构,支持多个LogRecorder的追加,添加LogRecorder的时候,调用register方法就注册到这个日志到框架中去了。

这个规则引擎实现了完全兼容Drools的14中规则运算操作,分别是:

  数值运算的操作符 :等于(==/EQUAL), 大于(>/GREATER), 小于(</LESS),不等于(!=/NOT_EQUAL),大于等于(>=/GREATER_EQUAL),小于等于(<=/LESS_EQUAL);

  字符串运算的操作符: 包含(INCLUDE/CONTAINS),不包含(NOT_INCLUDE/NOT CONTAINS),包含于(INCLUDED_BY/MEMBEROF),不包含于(NOT_INCLUDED_BY/NOT MEMBEROF),字符串相等(STRING_EQUAL),字符串不等(NOTSTRING_EQUAL),不区分大小写的字符串等于(EQUAL_IGNORE_CASE),不区分大小写的字符串不等(NOT_EQUAL_IGNORE_CASE),匹配(MATCH/MATCHES),不匹配(UNMATCH/NOT MATCHES)。

运算操作有2个字段构成,comparisonCode和comparisonValue,comparisonCode是额外定义的值,从01-20都是保留字段,comparisonValue是上述括号中的关键字(==,>等)。我们也可以通过继承AbstractComparisonOperator类来扩展运算操作符,添加属于自己的运算操作符。同样,需要调用register函数登记到框架中去。

在程序实现中,参考了Drools的框架的实现方法,因此干脆就做了一个Drools文件导入的模块,可以直接用Drools的drl文件了。为了做到灵活配置规则文件,除了drl文件外,也可以通过xml文件,和数据库表定义规则。 具体规则文件的定义和说明可以参考:

希望大家能够喜欢这个框架,也可以通过我的微信号联系我: woyishixinghren

Clone this wiki locally