使用场景
在日常开发中,业务中是否写了大量的 if-else?是否受够了这些 if-else 还要经常变动? 业务中是否做了大量抽象,发现新的业务场景还是用不上? 是否各种调研规则引擎,发现不是太重就是接入或维护太麻烦,最后发现还是不如硬编码?从最底层的编排思想,契合解耦和复用的属性,还你最大的编排自由度。
使用ice引擎配合Aviator表达式完成自定义规则完成热部署,由产品配置业务规则,流程上从 客户< == >产品< == >开发 转变为 客户< == >产品,能大大提高开发的工作效率。
本文模拟多字段逻辑处理,根据配置的条件得到用户对应的pstatus的判定值
服务端
ice文档地址:
链接: link
下载地址:
链接: link
服务端配置较为容易,按文档步骤部署即可,不做过多介绍
这里使用1.3版本
客户端
客户端的开发分为三个部分:
- 客户端配置
- 组件编写
- 界面配置业务逻辑
客户端配置
<!-- 引入 ice客户端-->
<dependency>
<groupId>com.waitmoon.ice</groupId>
<artifactId>ice-client-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
<!-- 引入 Aviator表达式 -->
<dependency>
<groupId>com.googlecode.aviator</groupId>
<artifactId>aviator</artifactId>
<version>5.2.6</version>
</dependency>
#ICE引擎
ice: #ice client配置
app: 5 #本项目注册服务端节点
# server: zookeeper:localhost:2181,localhost:2182,localhost:2183 #server高可用配置
server: 10.96.129.11:30027
scan: com.pec.erp.iceFlow #组件存在的包
pool: #线程池配置(用于并发关系节点)
parallelism: -1
组件编写
在nocas里面创建组件的包目录
编写表达式处理组件
@Data
@EqualsAndHashCode(callSuper = true)
public class AviatorFlow extends BaseLeafRoamFlow {
@IceField(name = "表达式取值",desc = "请填写表达式")
private String exp;//可供配置与热更新的Aviator表达式
private Expression compiledExpression;
@Override
protected boolean doRoamFlow(IceRoam roam) {
roam.put("pstatus",-1);
return (Boolean) compiledExpression.execute(roam);
}
public void setExp(String exp) { //为了更好的性能,设置/更新表达式时重新编译
this.exp = exp;
this.compiledExpression = AviatorEvaluator.compile(exp, true);
}
}
编写赋值组件
@Data
@EqualsAndHashCode(callSuper = true)
@IceNode(name = "设置状态值")
public class setValue extends BaseLeafRoamResult {
@IceField(name = "状态值")
private Integer setValue;
@Override
protected boolean doRoamResult(IceRoam roam) {
if (setValue == null) {
return false;
}
roam.put("pstatus",setValue);
return true;
}
}
这里启动服务端和客户端
界面配置业务逻辑
点击新增,appid为5的应用
新增一个项目的场景(可依据实际情况命名,不影响)
配置一个节点图,选择我们编写的组件61,表达式组件
选择我们编写的组件62,赋值组件
接口调用测试
@PostMapping("/getBillStatus")
public Integer getBillStatus(@RequestParam("bill") String bill) {
return billService.getBillStatus(bill);
}
@Override
public Integer getBillStatus(String bill) {
ErrorCheckEntity byNoAndAccId = errorCheckMapper.getIceRoamDetail(bill, 1);
IcePack pack = new IcePack();
pack.setScene("abnormal");
IceRoam iceRoam = null;
try {
iceRoam = JacksonUtils.readJson(JacksonUtils.toJsonString(byNoAndAccId), IceRoam.class);
pack.setRoam(iceRoam);
//TODO 把数据塞给 Ice.processCtx(pack) 执行
Object o = Ice.processCtx(pack).get(0).getPack().getRoam().get("pstatus");
return (Integer)o;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return -1;
}
重启客户端,测试一下
我们填写的表达式是:这是关于字段的判定exp:
status == 1 &&
isCollect == 2 &&
alipayInAmt != 0 &&
erpInAmt == 0 &&
taoPostFee - freightPrice == 0 &&
math.abs(erpOutAmt-alipayOutAmt) >= 0 &&
math.abs(erpOutAmt-alipayOutAmt) <= 1
debug里面查询数据库的值
验证测试结果为我们配置的数字:4
验证结果正确,后续复杂的业务逻辑和频繁变更,我们可以要求产品人员转换编排方式并exp表达式来应对。