目录

  • 前言
  • 一、监听器
  • 二、创建bpmn.xml
  • 三、测试

前言

本文主要用于测试在创建流程实例时,通过监听器动态修改任务的审批人。

一、监听器

实现 org.flowable.engine.delegate.TaskListener 接口,创建监听器

public class CreateProcessInstanceEvent implements TaskListener {@Overridepublic void notify(DelegateTask delegateTask) {String name = delegateTask.getName();System.out.println(name);if (name.equals("admin审批")){delegateTask.setAssignee("admin10");}}
}

二、创建bpmn.xml

通过 flowable-ui 的创建流程的界面设置监听器



然后保存并下载 bpmn 文件,在 userTask 里多了监听器的信息

<userTask id="sid-B6DF703A-E401-42A2-908C-D9F81E47FEC9" name="admin审批" flowable:assignee="admin" flowable:formFieldValidation="true"><extensionElements><flowable:taskListener event="create" class="com.iscas.biz.flowable.CreateProcessInstanceEvent"></flowable:taskListener><modeler:activiti-idm-assignee xmlns:modeler="http://flowable.org/modeler"><![CDATA[true]]></modeler:activiti-idm-assignee><modeler:assignee-info-email xmlns:modeler="http://flowable.org/modeler"><![CDATA[test-admin@example-domain.tld]]></modeler:assignee-info-email><modeler:assignee-info-firstname xmlns:modeler="http://flowable.org/modeler"><![CDATA[admin]]></modeler:assignee-info-firstname><modeler:assignee-info-lastname xmlns:modeler="http://flowable.org/modeler"><![CDATA[admin]]></modeler:assignee-info-lastname><modeler:initiator-can-complete xmlns:modeler="http://flowable.org/modeler"><![CDATA[false]]></modeler:initiator-can-complete></extensionElements></userTask>

三、测试

1、部署流程

@Testpublic void createDeployment() {Deployment deployment = repositoryService.createDeployment().addClasspathResource("process-test.bpmn20.xml").deploy();System.out.println(deployment.getId());}

2、启动流程

根据流程定义的 key process-test 启动流程

 @Testpublic void startProcessDefinition() {Map<String, Object> variables = new HashMap<String, Object>();variables.put("employee", "张三");variables.put("nrOfHolidays", 3);variables.put("description", "有事请假");ProcessInstance processInstance =runtimeService.startProcessInstanceByKey("process-test", variables);}

在创建程过程中,会回调监听器,下面分析一下 userTask 的流程

(1)executeOperations()

CommandInvoker 使用 while 循环继续调用新的 ExecutionEntity ,下面从调用 userTask 的 ContinueProcessOperation 开始

protected void executeOperations(final CommandContext commandContext) {FlowableEngineAgenda agenda = CommandContextUtil.getAgenda(commandContext);while (!agenda.isEmpty()) {Runnable runnable = agenda.getNextOperation();executeOperation(commandContext, runnable);}}

(2)ContinueProcessOperation.run()

     @Overridepublic void run() {// UserTask FlowElement currentFlowElement = getCurrentFlowElement(execution);if (currentFlowElement instanceof FlowNode) {continueThroughFlowNode((FlowNode) currentFlowElement);} else if (currentFlowElement instanceof SequenceFlow) {continueThroughSequenceFlow((SequenceFlow) currentFlowElement);} else {throw new FlowableException("Programmatic error: no current flow element found or invalid type: " + currentFlowElement + ". Halting.");}}

(3)continueThroughFlowNode

protected void continueThroughFlowNode(FlowNode flowNode) {...executeSynchronous(flowNode);...}

(4)executeSynchronous()

 protected void executeSynchronous(FlowNode flowNode) {...// Execute actual behavior//封装了用户任务和监听器等ActivityBehavior activityBehavior = (ActivityBehavior) flowNode.getBehavior();if (activityBehavior != null) {//执行 activityBehavior executeActivityBehavior(activityBehavior, flowNode);executeBoundaryEvents(boundaryEvents, boundaryEventExecutions);} else {executeBoundaryEvents(boundaryEvents, boundaryEventExecutions);LOGGER.debug("No activityBehavior on activity '{}' with execution {}", flowNode.getId(), execution.getId());CommandContextUtil.getAgenda().planTakeOutgoingSequenceFlowsOperation(execution, true);}}

(5)executeActivityBehavior()

protected void executeActivityBehavior(ActivityBehavior activityBehavior, FlowNode flowNode) {...activityBehavior.execute(execution);... }
     @Overridepublic void execute(DelegateExecution execution) {execute(execution, null);}
    @Overridepublic void execute(DelegateExecution execution, MigrationContext migrationContext) {CommandContext commandContext = CommandContextUtil.getCommandContext();ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService();//创建taskTaskEntity task = taskService.createTask();//设置属性task.setExecutionId(execution.getId());task.setTaskDefinitionKey(userTask.getId());task.setPropagatedStageInstanceId(execution.getPropagatedStageInstanceId());...//保存任务、历史任务、任务用户关联信息TaskHelper.insertTask(task, (ExecutionEntity) execution, !skipUserTask, (!skipUserTask && processEngineConfiguration.isEnableEntityLinks()));}...//回调监听器processEngineConfiguration.getListenerNotificationHelper().executeTaskListeners(task, TaskListener.EVENTNAME_CREATE);

(6)executeTaskListeners()

public void executeTaskListeners(TaskEntity taskEntity, String eventType) {if (taskEntity.getProcessDefinitionId() != null) {org.flowable.bpmn.model.Process process = ProcessDefinitionUtil.getProcess(taskEntity.getProcessDefinitionId());FlowElement flowElement = process.getFlowElement(taskEntity.getTaskDefinitionKey(), true);if (flowElement instanceof UserTask) {UserTask userTask = (UserTask) flowElement;//执行任务的监听器executeTaskListeners(userTask, taskEntity, eventType);}}}

(7)executeTaskListeners()

  public void executeTaskListeners(UserTask userTask, TaskEntity taskEntity, String eventType) {for (FlowableListener listener : userTask.getTaskListeners()) {//校验事件类型String event = listener.getEvent();if (event.equals(eventType) || event.equals(TaskListener.EVENTNAME_ALL_EVENTS)) {BaseTaskListener taskListener = createTaskListener(listener);if (listener.getOnTransaction() != null) {ExecutionEntity executionEntity = CommandContextUtil.getExecutionEntityManager().findById(taskEntity.getExecutionId());planTransactionDependentTaskListener(executionEntity, (TransactionDependentTaskListener) taskListener, listener);} else {taskEntity.setEventName(eventType);taskEntity.setEventHandlerId(listener.getId());try {//将任务封装到 TaskListenerInvocationCommandContextUtil.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(new TaskListenerInvocation((TaskListener) taskListener, taskEntity));} finally {taskEntity.setEventName(null);}}}}}

(8)handleInvocation()

 public void handleInvocation(DelegateInvocation invocation) {invocation.proceed();}
public void proceed() {invoke();}
 protected void invoke() {executionListenerInstance.notify(delegateTask);}
 public void notify(DelegateTask delegateTask) {//反射创建监听器对象  useClassForName ? Class.forName(className, true, classLoader) : classLoader.loadClass(className);TaskListener taskListenerInstance = getTaskListenerInstance();//调用监听器        CommandContextUtil.getProcessEngineConfiguration().getDelegateInterceptor().handleInvocation(new TaskListenerInvocation(taskListenerInstance, delegateTask));}

然后检查数据库的 ACT_RU_TASK 表 ,新增的任务的 assignee_ 字段被监听器修设置成了 admin10

flowable 监听器相关推荐

  1. Flowable 流程引擎系列文章导读

    Flowable 流程引擎系列文章导读 集成篇 入门教程篇 功能篇 其他问题 集成篇 Flowable 快速入门教程:SpringBoot 集成 Flowable + Flowable Modeler ...

  2. flowable集成spring boot ----任务监听器

    任务监听器 任务监听器(task listener)用于在特定的任务相关事件发生时,执行自定义的Java逻辑或表达式. 任务监听器包含下列属性: event(事件)(必填):触发任务监听器的任务事件类 ...

  3. Flowable全局监听器-待办消息提醒

    项目需要在每个待办Task到达时,发送一个消息提醒用户过来处理.不想在每个工作流单独加监听器,这时候可以使用Flowable的全局监听器. 定义一个监听器 package com.azhuzhu.fl ...

  4. 工作流引擎 SpringBoot+flowable完美结合,快速实现工作流,so easy

    flowable 起源 在2016.7~2017.5期间activiti团队内部已经产生了重大的分歧.关于新的activiti新团队与原有的团队重要开发人员我们罗列一下,细节如下: 上图是Tijs R ...

  5. Flowable学习笔记(二、BPMN 2.0-基础 )

    转载自  Flowable学习笔记(二.BPMN 2.0-基础 ) 1.BPMN简介 业务流程模型和标记法(BPMN, Business Process Model and Notation)是一套图 ...

  6. 工作流实战_23_flowable 任务监听器 事件监听器

    项目地址:https://gitee.com/lwj/flowable.git 分支flowable-base 视频讲解地址 https://www.bilibili.com/video/av7932 ...

  7. flowable用户组的处理

    背景 flowable有自己的用户账号信息,用户信息,用户组信息,其实这些用户信息都我们系统可能都存在,那么我们如何去使用一份数据呢? 1.我们可以建立视图直接取我们的组织信息,这个可以参考相关的文档 ...

  8. Flowable工作流入门

    Flowable工作流入门 本文链接:https://blog.csdn.net/qq_37059838/article/details/83576097 原作者:吕小小布 下载地址:Flowable ...

  9. Flowable工作流引擎技术方案

    应对越来越多的工作流使用场景,以及越来越灵活的业务情形,我们亟需对工作流引擎进行一次重构优化.目前市场上主流的工作流引擎,一种是我们熟知的activiti,另外一种就是flowable.众所周知,fl ...

最新文章

  1. android实现iphone风格的picker
  2. ActivityRouter
  3. Mybatis Plus——[Could not set property 'id' of '***' with value]解决方案
  4. [GAN学习系列3]采用深度学习和 TensorFlow 实现图片修复(中)
  5. linux查看编译器的大小端,Linux系统大小端判断
  6. 二级c语言考试改卷标准,计算机二级C语言笔试试卷
  7. [转载] python histogram函数_Python numpy.histogram_bin_edges函数方法的使用
  8. 设计模式:卑微的代理模式
  9. 在民间借贷软件开发中用到的电子文档存储技术
  10. fusioncharts java_FusionCharts在Java中的基本使用(2)
  11. 执行shellcode一直提示illegal instruction
  12. 加密流量分类-论文2:Deep Packet: A Novel Approach For Encrypted Traffic Classification Using Deep Learning
  13. 现在各种云建站,挑两个给大家分析一下。
  14. 未明学院:量化金融训练营开始报名,成为兼具数据分析技能+项目实战经验的复合型人才!
  15. 医学统计学 第五章(定性资料的统计描述)
  16. 登录模块与token的使用和创建
  17. 苹果cms10好看的模板
  18. OmniPlan Pro 3 for Mac v3.12.3 项目规划软件 中文破解版下载
  19. 关于linux的音频驱动
  20. 上传图片预览(服务器版)组件

热门文章

  1. 利用尾注插入参考文献
  2. openlayers5之聚合分析图层Cluster
  3. uni-app使用 (从下载到项目启动 流程 踩坑)
  4. 数据分析师必须掌握的常见数据分析方法
  5. 【毕业设计】深度学习+python+opencv实现动物识别 - 图像识别
  6. python:DataFrame的创建以及DataFrame的属性
  7. Python爬取15万条《我是余欢水》弹幕,看郭京飞如何演活极丧中年人
  8. Java IO流——异常及捕获异常 try…catch…finally
  9. BALER ace 相机的安装和配置
  10. jquery 同源下载图片到本地