flowable 监听器

目录

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


前言

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

一、监听器

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

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

二、创建bpmn.xml

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

flowable 监听器_第1张图片
flowable 监听器_第2张图片
然后保存并下载 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、部署流程

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

2、启动流程

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

	@Test
    public 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()

 	@Override
    public 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);
       ... 
    }
 	@Override
    public void execute(DelegateExecution execution) {
        execute(execution, null);
    }
    @Override
    public void execute(DelegateExecution execution, MigrationContext migrationContext) {
CommandContext commandContext = CommandContextUtil.getCommandContext();
        ProcessEngineConfigurationImpl processEngineConfiguration = CommandContextUtil.getProcessEngineConfiguration();
        TaskService taskService = processEngineConfiguration.getTaskServiceConfiguration().getTaskService();

		//创建task
        TaskEntity 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 {
                    	//将任务封装到 TaskListenerInvocation
                        CommandContextUtil.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,flowable)