没有规定,不成方圆;一、背景前段时间,在做我的项目重构的时候,遇到很多中央须要做很多的条件判断。当然能够用很多的if-else判断去解决,然而过后也不分明怎么回事,就想玩点别的。于是乎,就去调研了规定引擎。
当然,市面上有很多成熟的规定引擎,性能很多,性能很好。然而,就是想玩点不一样的(大家做技术选型别这样,这个是反面教材)。最终一款URule的规定引擎吸引了我,次要还是采纳浏览器可间接配置,不须要过多装置,可视化规定也做的不错。通过一系列调研,前面就把它接入了我的项目中,顺便记录下调研的后果。
二、介绍规定引擎其实是一种组件,它能够嵌入到程序当中。将程序简单的判断规定从业务代码中剥离进去,使得程序只须要关怀本人的业务,而不须要去进行简单的逻辑判断;简略的了解是规定承受一组输出的数据,通过预约好的规定配置,再输入一组后果。
当然,市面上有很多成熟的规定引擎,如:Drools、Aviator、EasyRules等等。然而URule,它能够运行在Windows、Linux、Unix等各种类型的操作系统之上,采纳纯浏览器的编辑模式,不须要装置工具,间接在浏览器上编辑规定和测试规定。
当然这款规定引擎有开源和pro版本的区别,至于pro版是啥,懂的都懂,上面放个表格,理解下具体的区别
个性PRO版开源版向导式决策集有有脚本式决策集有有决策树有有决策流有有决策表有有穿插决策表有无简单评分卡有无文件名、我的项目名重构有无参数名、变量常量名重构有无Excel决策表导入有无规定集模版保留与加载有无中文我的项目名和文件名反对有无服务器推送常识包到客户端性能的反对有无常识包优化与压缩的反对有无客户端服务器模式下大常识包的推拉反对有无规定集中执行组的反对有无规定流中所有节点向导式条件与动作配置的反对有无循环规定多循环单元反对有无循环规定中无条件执行的反对有无导入我的项目主动重命名性能有无规定树构建优化有无对象查找索引反对有无规定树中短路计算的反对有无规定条件冗余计算缓存反对有无基于计划的批量场景测试性能有无常识包调用监控有无更为欠缺的文件读写权限管制有无常识包版本控制有无SpringBean及Java类的热部署有无技术支持有无三、装置应用理论应用时,有四种应用URule Pro的形式,别离是嵌入式模式、本地模式、分布式计算模式以及独立服务模式。
然而咱们这里不思考URule Pro,咱本人整个开源版,在开源版集成springboot的根底上做一个二次开发,搜了一圈,其实就有解决方案。大抵的我的项目模块如下:本人创立个空数据库,只须要在edas-rule-server服务中批改下数据库的配置,而后启动服务即可。第一次启动实现,数据库中会创立表。
spring.datasource.type=com.alibaba.druid.pool.DruidDataSourcespring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/urule-data?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=falsespring.datasource.username=rootspring.datasource.password=mysql下面说过,它是纯用浏览器进行编辑,配置规定的,只须要关上浏览器,输出地址:http://localhost:8090/urule/frame,看到这个界面,就阐明启动胜利了。
四、根底概念3.1整体介绍先说下URule它的形成局部,次要是两局部:1、设计器局部 2、规定执行引擎。设计器局部次要是库文件和规定文件形成。上面看下整体的结构图
3.2库文件如上图介绍的,库文件有4种,包含变量库,参数库,常量库和动作库。其实相似于Java开发的零碎中的实体对象,枚举,常量以及办法。
下面说过,规定都是可视化配置的。在配置规定的过程中,就须要引入各种曾经定义好的库文件,再联合业务需要,从而配置出合乎业务场景的业务规定,所以哪里都有库文件的身影。
3.2.1变量库文件在业务开发中,咱们会创立很多Getter和Setter的Java类,比方PO、VO、BO、DTO、POJO等等,其实这些类new对象后次要起到的作用就是数据的载体,用来传输数据。
在URule中,变量库就是用来映射这些对象,而后能够在规定中应用,最终实现业务和规定的互动。最初上一张图,用来创立变量库对了,下面废话了这么多可视化配置,这才是第一次展现配置界面,羞愧羞愧。
上图高深莫测,在“库”这个菜单底下右键,而后点击增加变量库即可,最初定义本人喜爱的变量库名,当然名字只反对中文或者英文,其余字符不可用。创立完变量库后,就能够对变量库进行编辑,能够认为就是给POJO增加属性也不弯弯绕绕讲什么术语,就集体了解。图右边是创立类,其中名称是它的别名,配置规定用它代替这个类。图左边是类的属性,我这里轻易写了几个,预计看了懂得都懂。
最初在业务零碎中创立对应的类,留神全限定名和配置变量库的类门路统一。
package com.cicada;import com.bstek.urule.model.Label;import lombok.Data;/** * @author 往事如风 * @version 1.0 * @date 2023/3/3 15:38 * @description */@Datapublic class Stu { @Label("姓名") private String name; @Label("年龄") private int age; @Label("班级") private String classes;}最初说下这个@Label注解,这个是由URule提供的注解,次要是形容字段的属性,跟变量库的题目一栏统一就行。听官网介绍能够通过这个注解,实现POJO属性和变量库属性映射。就是POJO写好,而后对应规定的变量库就不须要从新写,能够间接生成。反正就有这个性能,这里就间接一笔带过了。
3.2.2常量库文件说到常量库,这个就能够认为是咱们Java零碎中的常量,枚举。比方性别,要定义枚举吧;比方对接的机构,也能够定义一个枚举吧。
当然,相似于变量库,常量库也能够实现和零碎中的枚举互相映射,这样做的益处能够防止咱们手动输出,避免输出谬误。创立常量库也比较简单,间接在“库”这个菜单下右键,“增加常量库”。
创立好常量库文件后,也会呈现如下页面:
3.2.3参数库文件参数库,就是URule规定中的长期变量,变量的类型和数量不固定。能够认为相似于Map,实际上存储参数库的也就是个Map。
同样的套路,间接在“库”这个菜单下右键,“增加参数库”。能够看到,参数库曾经少了右边分类这一项,间接增加参数,抉择类型就是干,绝对简略了很多。“名称”这列我这里用了英文,就是Map中的key,而“题目”这列就是在配置规定时候显示用的,中文看着比拟直观。
当然还须要留神的点是,定义的名称要保障惟一,因为Map中的key是惟一的,不然就会存在笼罩的状况。3.2.4动作库文件动作库能够对配置在spring中的bean办法进行映射,而后能够在规定中间接调用这批办法。习用套路,还是在“库”菜单下右键,点击“增加动作库”。而后我在零碎中增加了一个类Action,而后在类上标记@Component注解,将该类交给spring的bean容器治理。该类中增加一些办法,在办法上标记@ExposeAction注解,该注解是URule定义的,阐明被标记的办法都会被动作库读取到。
package com.bstek.urule.cicada;import com.bstek.urule.action.ActionId;import com.bstek.urule.model.ExposeAction;import org.springframework.stereotype.Component;import java.text.SimpleDateFormat;import java.util.Date;/** * @author 往事如风 * @version 1.0 * @date 2023/3/10 13:59 * @description */@Component("action")public class Action { @ActionId("Hello") public String hello(){ return "hello"; } @ExposeAction(value="办法1") public boolean evalTest(String username){ if(username==null){ return false; }else if(username.equals("张三")){ return true; } return false; } @ExposeAction(value="测试Int") public int testInt(int a,int b){ return a+b; } @ExposeAction(value="打印内容") public void printContent(String username, Date birthday){ SimpleDateFormat sd=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); if(birthday!=null){ System.out.println(username+"往年曾经"+sd.format(birthday)+"岁了!"); }else{ System.out.println("Hello "+username+""); } } @ExposeAction(value="打印Stu") public void printUser(Stu m){ System.out.println("Hello "+m.getName()+", is age:"+m.getAge()); }}最初在动作库页面上增加bean,“Bean Id”一列输出对应的spring bean的名称,这里输出action。而后点击操作列中的小手按钮,就会弹出刚在Action类中标记了ExposeAction注解的办法。抉择一个指定的办法增加进来,最初看到办法对应的参数也会被主动加载进去。
...