参考https://blog.csdn.net/rishengcsdn/article/details/90480771,前一章内容简述了如何搭建一个流程引擎框架。
这章讲述如何使用定时事件和信号事件构建一个异步的服务业务。
源代码下载地址:https://download.csdn.net/download/rishengcsdn/11200394
参考业务流程图如下:
流程启动以后,会进入一个循环等待的定时任务中,每10秒执行一次黑名单规则的业务逻辑。等待无限次,直到业务流程获得一个信号blackRule,此时会结束业务的死循环,进入下一个业务获取黑名单结果的业务逻辑,并且最终结束。
这张业务流程图有几个关键点,首先是事件网关:
一.事件网关
什么是事件网关?
基于事件的网关,允许基于事件做选择。
事件网关的执行原理?
网关的每一条出口顺序流,都需要连接至一个捕获中间事件。当流程执行到达基于事件的网关时,网关类似等待状态地动作:执行被暂停。并且,为每一条出口顺序流,创建一个事件订阅。流程的走向完全是由于中间事件的选择。而由哪一个事件来决定流程的走向则是由最先触发的事件来决定的。
事件网关和其他网关的区别
请注意基于事件的网关,其出口顺序流与一般的顺序流不同。这些顺序流从不实际被执行。相反,它们允许流程引擎决定,当执行到达一个基于事件的网关时,需要订阅什么事件。
约束:
1)一个基于事件的网关,必须有两条或更多的出口顺序流。
2)基于事件的网关,只能连接至 intermediateCatchEvent(捕获中间事件) 类型的元素(Activiti不支持基于事件的网关后,连接接收任务,Receive Task)。
3)连接至基于事件的网关的 intermediateCatchEvent ,必须只有一个入口顺序流。
二,定时事件
定时器事件是根据指定的时间触发的事件。可以用于 开始事件, 中间事件 或 边界事件。
定时事件的规则可以参考手册,此处的例子是要求业务等待10秒钟。据说还可以设置cron表达式指定timeCycle。
启用定时事件需要修改activiti.cfg.xml或者Spring的applicationContext-activiti.xml,将
三,信号事件
信号事件会引用一个已命名的信号。信号全局范围的事件(广播语义)。 会发送给所有激活的处理器。
信号事件定义使用signalEventDefinition
元素。 signalRef
属性会引用definitions
根节点里定义的signal
子元素。
此处例子订阅了blackRule信号。没有信号,业务流程永远不会结束。
下面是部分代码说明:
===========================================================================
流程配置文件:7OWxvczjpzt.bpmn20.xml
===========================================================================
ActiviController.java增加了两个方法:
@RequestMapping(value = "/test/testFlow3", method = RequestMethod.GET)
public String testFlow3() throws Exception {
String retMsg=activiService.doTest3();
return retMsg;
}
@RequestMapping(value = "/test/testFlow4", method = RequestMethod.GET)
public String testFlow4() throws Exception {
String retMsg=activiService.doTest4();
return retMsg;
}
===========================================================================
ActiviService.java也增加了两个方法:
/**
* 启动定时任务流程
* @return
* @throws FileNotFoundException
*/
public String doTest3() throws FileNotFoundException {
// 部署流程文件
String filePath = "D:/workSpace/activiTest/src/main/resources/org/activiti/test/7OWxvczjpzt.bpmn20.xml";
FileInputStream fis = new FileInputStream(filePath);
repositoryService.createDeployment().addInputStream("userAndGroupInUserTask.bpmn", fis).deploy();// 用userAndGroupInUserTask.bpmn作为资源名称
Map
// variables.put("blackTaskImpl1", new BlackTaskImpl1());
// variables.put("blackTaskImpl2", new BlackTaskImpl2());
// 启动流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("OWxvczjpzt", variables);
// 发送信号完成支付
//runtimeService.signalEventReceived("blackRule");
return "定时任务流程启动";
}
/**
* 发送信号结束定时任务死循环
* @return
* @throws FileNotFoundException
*/
public String doTest4() throws FileNotFoundException {
// 发送信号
runtimeService.signalEventReceived("blackRule");
return "信号事件发送成功";
}
===========================================================================
新增加的业务服务类1:
/**
* 服务节点执行的任务
*/
@Service(value="blackTaskImpl1")
public class BlackTaskImpl1 implements Serializable,JavaDelegate {
private int i=0;
@Override
public void execute(DelegateExecution execution) throws Exception {
// Thread.sleep(10000);
Map
taskVariables.put("message", "TO 定时事件");
i++;
if(i>3){
execution.setVariable("message", "TO 信号事件");
}else{
execution.setVariable("message", "TO 定时事件");
}
System.out.println("variavles=" + execution.getVariables());
System.out.println("事件执行次数:"+i);
}
}
===========================================================================
新增加的业务服务类2:
/**
* 服务节点执行的任务
*/
@Service(value="blackTaskImpl2")
public class BlackTaskImpl2 implements Serializable,JavaDelegate {
@Override
public void execute(DelegateExecution execution) throws Exception {
RuntimeService runtimeService = execution.getEngineServices().getRuntimeService();
TaskService taskService = execution.getEngineServices().getTaskService();
System.out.println("variavles=" + execution.getVariables());
System.out.println("信号事件执行次数:");
}
}
===========================================================================
启动注册中心和activiTest两个项目,然后访问业务地址:
http://localhost:8089/test/testFlow3
页面上的结果为:
定时任务流程启动
从后台控制台可以看到每10秒输出一下如下的日志:
variavles={message=TO 定时事件}
事件执行次数:1
variavles={message=TO 定时事件}
事件执行次数:2
variavles={message=TO 定时事件}
事件执行次数:3
等待事件越长,事件执行次数越多。说明业务已经进入死循环,在等待结束的信号。
访问业务地址:
http://localhost:8089/test/testFlow4
页面输出:
信号事件发送成功
从后台控制台看到如下结果:
variavles={message=TO 定时事件}
事件执行次数:1
variavles={message=TO 定时事件}
事件执行次数:2
variavles={message=TO 定时事件}
事件执行次数:3
variavles={message=TO 信号事件}
事件执行次数:4
variavles={message=TO 信号事件}
事件执行次数:5
variavles={message=TO 信号事件}
事件执行次数:6
variavles={message=TO 信号事件}
信号事件执行次数:
事件执行次数不再增加,说明业务流程已经结束。