Skip to content
本页目录

服务逻辑编排

服务逻辑编排是一种基于流的编程,是一种数据流编程范式,也是一种基于组件的软件工程方式。 通过将程序分解为可重用的组件,定义其输入和输出端口;再把多个组件连接起来,形成一个数据流图,就是一个服务逻辑进程; 多个服务逻辑进程就可以实现一个业务应用的服务逻辑。

服务的常规需求

一个服务接口,一般逻辑如下:

null

在这个过程中,复杂度主要集中在Service中,需要变量(定义、赋值)、判断、循环(跳出循环、进入下一个循环)、返回、异常(抛出和捕获)、事件(监听和触发)、定时执行、延时执行、调用(其他Service和其他接口)、事务和超时处理等。

变量

给变量赋予常量、时间以及其他表达式,可以实现变量赋值或者计算,通过组件完成

类似Java代码:

java
String a = '123';
a = a + 1;

Date now = new Date();

判断

可以提供跳过条件排他网关并行网关包容网关,实现判断逻辑

跳过条件

在组件上设置跳过条件,当表达式成立时,跳过执行组件逻辑,直接进入后续逻辑

类似Java逻辑如下:

java
if(!skipCondition) {
  // 执行业务逻辑
}

排他网关

按顺序,执行第一个满足条件的分支

类似Java逻辑如下:

java
if (conditionA) {
  // 分支1
} else if (conditionB) {
  // 分支2
} else {
  // 默认分支
}

switch (key) {
case A:
  // 分支1
  break;
case B:
  // 分支2
  break;
default:
  // 默认分支
  break;
}

并行网关

逻辑编排中并行网关作用不大,由于机制问题,并行和串行没有太大差别;

汇聚规则:当所有入口线都执行完成后,才能往后执行

包容网关

执行满足条件的所有分支

类似Java逻辑如下:

java
if (conditionA || conditionB) {
  if (conditionA) {
    // 分支1
  }
  if (conditionB) {
    // 分支2
  }
} else {
  // 分支1、2都不成立
}

汇聚规则:不存在激活的节点能到达网关时,即可往后执行

循环

使用多实例方式实现循环逻辑

类似Java逻辑如下:

java
for(Object item: items) {
  // 业务逻辑
}

for(int i = 0; i < items.size(); i++){
  Object item = items[i];
  // 业务逻辑
}

多实例特征中,可以使用跳过条件来实现continue,使用完成条件实现 break

多实例子流程中,也可以使用空结束事件终止结束事件,分别实现循环中的 continuebreak

类似Java逻辑如下:

java
for(int i = 0; i < items.size(); i++){
  Object item = items[i];
  if (conditionA) {
    continue; // 空结束事件
  }
  ...
  if (conditionB) {
    break; // 终止结束事件
  }
  ...
}

代码块/内部方法

循环过程中,经常需要组合各种逻辑,此时可以使用子流程 SubProcess 实现

类似Java逻辑如下:

java
for(Object item: items){
  // 代码块开始
  item.disabled = false;
  list.add(item)
  ...
  // 代码块结束
}

返回

多分支场景时,可以采用终止结速事件来实现返回

类似Java逻辑如下:

java
if (condition){
  return;
}
...

异常

组件执行有异常时,会触发对应的错误边界事件,没有定义错误边界事件时,会抛出异常;

类似Java逻辑如下:

java
try {
  // 业务逻辑
} catch (Exection e) {
  if (有对应的错误边界事件) {
    // 触发错误边界事件
  } else {
    throw e;
  }
}

通过错误结束事件,可以实现抛出自定义事件

类似Java逻辑如下:

java
throw new Exception('错误code')

事件

信号抛出中间事件和信号捕获中间事件,可以实现监听指定事件并执行对应逻辑的能力。信号默认在全局范围内传播,所有进程都可以监听到,可以通过设置scope值为processInstance将信号限制在一个Process实例中。

类似Java逻辑如下:

java
public class EventManager {  
    private List<EventObserver> observers = new ArrayList<>();  
  
    public void addObserver(EventObserver observer) {  
        observers.add(observer);  
    }  
  
    public void removeObserver(EventObserver observer) {  
        observers.remove(observer);  
    }  
  
    public void notifyObservers(String eventName) {  
        for (EventObserver observer : observers) {  
            if (observer.getEventName().equals(eventName)) {  
                observer.execute();  
            }  
        }  
    }  
}  
...
class MsgNameObserver implements EventObserver {  
    @Override  
    public String getEventName() {  
        return "msgName";  
    }  
  
    @Override  
    public void execute() {  
        // 你的逻辑代码  
    }  
}
...
EventManager eventManager = new EventManager();  
MsgNameObserver msgNameObserver = new MsgNameObserver();  
eventManager.addObserver(msgNameObserver);  // 监听事件
eventManager.notifyObservers("msgName");    // 触发事件

延时执行

定时器捕获中间事件,可以实现延时执行

类似Java逻辑如下:

java
Thread.sleep(1000);

如果是需要异步等待一定时间或定时执行逻辑,就教用定时执行Service

调用API

提供组件,实现各种类型的API调用

调用其他Service

使用CallAcivity组件,实现调用其他Service

事务

一个进程可以设定启用事务,当进程中局部组件需要独立事务时,可采用事务子流程。 针对一个事务范围内的所有数据库操作组件,如果共用一个数据源的,采用本地事务,否则采用JTA事务。

超时

一个进程可以设定超时时间,当时间超时后,进程中的组件将不再执行,并抛出超时异常。

每个组件也可以设置超时时间,当时间超时后,组件内部逻辑将不再执行(需要组件支持),多实例时,设置的超时时间为所有实例执行完成的时间,超时后,后续实例将不再执行,并抛出超时异常。

定时执行

由统一的任务调度服务管理所有进程的定时执行。也可以用API调用组件来自动添加、删除定时任务。

全局事件

由统一的事件总线完成,可以设置监听事件来启动进程执行。也可以用API调用组件来自动注册和触发事件。

进程的定义

像流程图一样,把多个可重用的组件连接成一个数据流图,即可定义一个进程,示例如下:

null

XML定义

参考 BPMN 定义规范,逻辑编排相关定义如下:

名称节点名说明
进程Process每个逻辑编排一个进程
顺序流SequenceFlow组件执行顺序,有条件判断是否可以通行

网关

名称节点名说明
排他网关ExclusiveGateway条件判断
并行网关ParallelGateway无异步任务时,和顺序执行没有差异
包容网关InclusiveGateway多分支条件同时满足的情况

事件

名称节点名说明
开始事件StartEvent逻辑编排入口,仅一个
结束事件EndEvent结束节点,可多个
终止结束事件流程或子流程实例强制结速
信号捕获中间事件监听信号(全局或进程实例内)
信号抛出中间事件触发信号(全局或进程实例内)

组件

名称节点名说明
执行SQLSQLTask编码、名称、入口、出口、跳过执行表达式
单表操作TableTask
接口调用APITask
脚本执行GroovyTask
内嵌子流程SubProcess
调用子流程CallActivity
事务子流程Transaction

边界事件

名称节点名说明
错误边界事件BoundaryEvent编码、名称、出口

逻辑编排场景分析

顺序执行场景

组件按顺序执行

null

分支场景

根据动作不同,可以转移到不同的状态

null

带条件的转移场景

动作发生后,根据转移条件,转移到不同的状态

null

退回场景1:使用不同状态标记退回数据

使用一个新状态来表示退回状态

null

退回场景2:使用相同状态标记退回数据

使用原状态,但用一个退回状态标记来表示退回状态

null

逻辑编排的使用

执行逻辑流

java
public static void start(String logicFlowCode, DelegateExecution execution)

内部资料,请勿外传