网关用来控制流程的流向,简而言之,当流程实例在运转过程中,从一个节点跳转到下一个节点时,需要人为的控制某些条件,即只有满足这些条件的时候才会触发节点的跳转时,就可以考虑使用网关
activity提供了多种网关可供选择使用,从插件的流程设计器中大致可以看到有多种网关,分别是:并行网关、排他网关、包含网关以及基于事件类型的网关
排他网关 Exclusive Gateway
排他网关又叫互斥网关,条件计算为true的顺序流才会被选择继续流程,有且只有一条流程出线的出口,如果出现多个条件为true,则会默认选择第一条true来执行,如果没有条件输出true,流程走到这一步的时候则会报错
并行网关 Parallel Gateway
它可以将执行分支(fork)为多条路径,也可以合并(join)执行的多条入口路径。简单来说就是,并行网关它可以有多条入口和出口,并在合并入口处会等待其他分支执行完,然后再执行后面流程,另外,需注意的是,并行网关没有条件的概念,即便设置了条件,它会自动忽略,而排它网关需要在定义流程模板时设定条件
用内部带有’圆圈’图标的网关(菱形)表示,这个网关比较特殊,它集合了前面两个网关的特点,一句话来说就是,它既可以像排他网关那样设置条件,也能像并行网关这样设置多条分支并行执行,在上图中,当流程启动后,如果流程变量paymentReceived == false 且shipOrder == true,将会创建两个任务。如果只有一个流程变量等于true,则只会创建一个任务。如果没有条件计算为true,会抛出异常,并可通过指定出口顺序流,总结起来就是:
分支:
所有外出顺序流的条件都会被解析,结果为 true 的顺序流会以并行方式继续执行, 会为每个顺序流创建一个分支
汇聚:
所有并行分支到达包含网关,会进入等待状态, 直到每个包含流程 token 的进入顺序流的分支都
到达。 这是与并行网关的最大不同。换句话说,包含网关只会等待被选中执行了的进入顺序流。 在
汇聚之后,流程会穿过包含网关继续执行
基于事件的网关 Event-based Gateway
这个网关相比其他三个网关,用的相对没那么多,主要还是根据业务需求而定,该网关在执行出口处,要连接一个捕获中间事件。当流程执行到该网关时,流程类似处于等待的状态,此时执行被暂停,并创建一个事件订阅;
需要订阅什么事件。基于下列约束:
下面我们分别用代码简单演示一下上述几种网关的使用
如图所示,我们的需求是,当请假天数小于3天的时候走部门经理审批,大于3天时走总经理审批,如果不用网关,采用之前我们讲过的设置条件变量的方式理论上也是可以实现的,这里如果更改为排它网关流程图变成怎样的呢?
排它网关的条件设置也很简单,只需要双击流程线,再在左边的condition上面设置条件变量即可
2、部署和启动流程实例
//部署
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deployment =
repositoryService.createDeployment().addClasspathResource("process/gate/exelusive.bpmn").name("exelusive").deploy();
System.out.println(deployment.getId());
System.out.println(deployment.getName());
}
//启动流程
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
Map params = new HashMap<>();
params.put("day",5);
runtimeService.startProcessInstanceByKey("execlusive1",params);
}
简单来说,在启动流程实例的时候,需要将我们在流程图中设置的请假天数的变量设置进去,比如我这里传进去的天数为5,看看经过人事主管审批之后会走到哪里呢?我们先观察一下任务表数据吧,目前走到第一个节点了
2、完成第一个节点审批
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
String taskId = "2506";
taskService.complete(taskId);
System.out.println("审批完成");
}
运行上面的代码,这时候我们刷新任务表数据,可以惊奇的发现直接走到了总经理审批,这个就是网关自身帮助我们完成的
最后完成总经理审批即可,当然,大家还可以测试一下当请假天数小于3的情况比较简单,这里就不继续演示了
1、定义流程文件
关于并行网关的基本概念在上文中有所交代,下面我们继续考虑这样一个需求,在实际业务场景中,当总经理审批完结后,后续的工作是不是就完成了呢?当然不是,还有其他的部门需要配合工作啊,比如说行政或者人事部门要统计考勤,财务部门要计算工资等,但是这些不同部门的工作又不是互相影响的,却又是总经理审批完成后都要进入的分支,那么这时候并行网关就排上用场了,我们接着上面的流程文件进行绘制做简单的改造
2、部署并启动流程实例
//部署
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deployment =
repositoryService.createDeployment().addClasspathResource("process/gate/exelusive.bpmn").name("exelusive").deploy();
System.out.println(deployment.getId());
System.out.println(deployment.getName());
}
//启动流程
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
Map params = new HashMap<>();
params.put("day",5);
runtimeService.startProcessInstanceByKey("execlusive1",params);
}
这个和上面的类似
3、完成人事主管审批和总经理审批
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
String taskId = "2506";
taskService.complete(taskId);
System.out.println("审批完成");
}
运行完上述的代码后,我们观察任务表,发现产生了两条任务数据,这也很好理解,既然是并行的任务,需要各自进行审批然后再做汇聚
3、分别完成财务审批和行政审批
这里只需要将各自的taskId带入到上面的代码中运行即可
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
String taskId = "7504";
taskService.complete(taskId);
System.out.println("审批完成");
}
审批完毕后,任务表清空
同时在历史任务实例表可以清楚看到各个审批任务的执行情况
需求,在就诊过程中,根据就医用户的类型,我们定义有3种,即条件变量type分别是1,2,3,不同的类型表示在就医过程中服务流程不一样(这里仅作假设),3表示可以享受任意一种类型的就医过程,2可以享受前两种,而1表示享受第一种
包含网关在这里起到的作用是,如果某种类型的用户过来之后,会根据type的不同走不同的分支,可以走其中一个,也可能多个都走,即满足多个设定的条件,最后进行汇聚
和上面的网关类似,定义完网关后,在每个不同的网关出线上面定义条件即可
2、部署和启动流程
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Deployment deployment =
repositoryService.createDeployment().addClasspathResource("process/gate/include.bpmn").name("exelusive").deploy();
System.out.println(deployment.getId());
System.out.println(deployment.getName());
}
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
Map params = new HashMap<>();
params.put("type",2);
runtimeService.startProcessInstanceByKey("include1",params);
}
3、完成第一个节点审批
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
String taskId = "2506";
taskService.complete(taskId);
System.out.println("第一节点审批完成");
}
这时再次观察任务表,发现产生了两条任务,我们简单分析下,包含网关表示任何一个预期的条件满足的时候即执行,我们在上面启动实例的时候设置的是2,即同时满足第一个分支和第二个分支的条件因此产生了两条任务,
4、分别完成常规就诊的任务和抽血化验的任务
public static void main(String[] args) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
TaskService taskService = processEngine.getTaskService();
String taskId = "5004";
taskService.complete(taskId);
System.out.println("第一节点审批完成");
}
最后再来看一下历史流程实例表,可以清楚看到每个流程实例的执行
以上便是本篇关于网关简单使用的总结,搞清楚了其配置和使用原理,并不是很难,难点在于如何结合自身的业务配置相关的条件变量合理的进行组合,基于事件的网关大家有兴趣还可以继续研究,这里限于篇幅就不再讲解了
本篇到此结束,最后感谢观看!