This article is shared from Huawei cloud community< A use example, five operation steps! From then on, you can easily master the development of workflow in the project >, by Chova the siege lion.
This paper introduces the use of workflow Activiti framework in detail through a specific use example of workflow Activiti framework. It includes creating a process, publishing a process, starting a process instance, completing a process instance, and suspending and activating a process instance. By mastering the specific use steps of workflow Activiti, you can basically learn the workflow and specific use of workflow Activiti.
Create process
- To operate the Activiti engine, you need to go through org Activiti. engine. The services exposed by the processengine instance You can operate an org Activiti. engine. ProcessEngine
- Create a leave application workflow:
Release process
- Any data related to "static" resources (such as process definitions) can be accessed through the repository service. Conceptually, all static data is the resource content of Activiti
- Create a new XML file in src/test/resources/org/activiti/test directory bpmn20. xml:
<?xml version="1.0" encoding="UTF-8" ?> <definitions id="definitions" targetNamespace="http://activiti.org/bpmn20" xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:activiti="http://activiti.org/bpmn"> <process id="vacationRequest" name="Vacation request"> <startEvent id="request" activiti:initiator="employeeName"> <extensionElements> <activiti:formProperty id="numberOfDays" name="Number of days" type="long" value="1" required="true"/> <activiti:formProperty id="startDate" name="First day of holiday (dd-MM-yyy)" datePattern="dd-MM-yyyy hh:mm" type="date" required="true" /> <activiti:formProperty id="vacationMotivation" name="Motivation" type="string" /> </extensionElements> </startEvent> <sequenceFlow id="flow1" sourceRef="request" targetRef="handleRequest" /> <userTask id="handleRequest" name="Handle vacation request" > <documentation> ${employeeName} would like to take ${numberOfDays} day(s) of vacation (Motivation: ${vacationMotivation}). </documentation> <extensionElements> <activiti:formProperty id="vacationApproved" name="Do you approve this vacation" type="enum" required="true"> <activiti:value id="true" name="Approve" /> <activiti:value id="false" name="Reject" /> </activiti:formProperty> <activiti:formProperty id="managerMotivation" name="Motivation" type="string" /> </extensionElements> <potentialOwner> <resourceAssignmentExpression> <formalExpression>management</formalExpression> </resourceAssignmentExpression> </potentialOwner> </userTask> <sequenceFlow id="flow2" sourceRef="handleRequest" targetRef="requestApprovedDecision" /> <exclusiveGateway id="requestApprovedDecision" name="Request approved?" /> <sequenceFlow id="flow3" sourceRef="requestApprovedDecision" targetRef="sendApprovalMail"> <conditionExpression xsi:type="tFormalExpression">${vacationApproved == 'true'}</conditionExpression> </sequenceFlow> <task id="sendApprovalMail" name="Send confirmation e-mail" /> <sequenceFlow id="flow4" sourceRef="sendApprovalMail" targetRef="theEnd1" /> <endEvent id="theEnd1" /> <sequenceFlow id="flow5" sourceRef="requestApprovedDecision" targetRef="adjustVacationRequestTask"> <conditionExpression xsi:type="tFormalExpression">${vacationApproved == 'false'}</conditionExpression> </sequenceFlow> <userTask id="adjustVacationRequestTask" name="Adjust vacation request"> <documentation> Your manager has disapproved your vacation request for ${numberOfDays} days. Reason: ${managerMotivation} </documentation> <extensionElements> <activiti:formProperty id="numberOfDays" name="Number of days" value="${numberOfDays}" type="long" required="true"/> <activiti:formProperty id="startDate" name="First day of holiday (dd-MM-yyy)" value="${startDate}" datePattern="dd-MM-yyyy hh:mm" type="date" required="true" /> <activiti:formProperty id="vacationMotivation" name="Motivation" value="${vacationMotivation}" type="string" /> <activiti:formProperty id="resendRequest" name="Resend vacation request to manager?" type="enum" required="true"> <activiti:value id="true" name="Yes" /> <activiti:value id="false" name="No" /> </activiti:formProperty> </extensionElements> <humanPerformer> <resourceAssignmentExpression> <formalExpression>${employeeName}</formalExpression> </resourceAssignmentExpression> </humanPerformer> </userTask> <sequenceFlow id="flow6" sourceRef="adjustVacationRequestTask" targetRef="resendRequestDecision" /> <exclusiveGateway id="resendRequestDecision" name="Resend request?" /> <sequenceFlow id="flow7" sourceRef="resendRequestDecision" targetRef="handleRequest"> <conditionExpression xsi:type="tFormalExpression">${resendRequest == 'true'}</conditionExpression> </sequenceFlow> <sequenceFlow id="flow8" sourceRef="resendRequestDecision" targetRef="theEnd2"> <conditionExpression xsi:type="tFormalExpression">${resendRequest == 'false'}</conditionExpression> </sequenceFlow> <endEvent id="theEnd2" /> </process> </definitions>
- In order for Activiti engine to know this process, we must first [publish]. Publishing means that the engine will parse BPMN 2.0 xml into executable things, and all process definitions in the publishing package will be added to the database In this way, when the engine restarts, it can still obtain the [published] process:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); RepositoryService repositoryService = processEngine.getRepositoryService(); repositoryService.createDeployment() .addClasspathResource("org/activiti/test/VacationRequest.bpmn20.xml") .deploy(); Log.info("Number of process definitions: " + repositoryService.createProcessDefinitionQuery().count());
Start a process instance
- After publishing the process definition to the Activiti engine, you can initiate a new process instance based on it
- For each process definition, there can be many process instances A process definition is a "blueprint", and a process instance is a running execution of it
- All things related to the running state of the process can be obtained through the RuntimeService There are many ways to start a new process instance
- You can add some process variables when the process instance starts, because the expression of the first user task requires these variables Process variables are often used because they give special meaning to different process instances from the same process definition
- Process variables are the key to distinguish process instances
- Next, use the key defined in the process definition xml to start the process instance:
Map<String, Object> variables = new HashMap<String, Object>(); variables.put("employeeName", "Kermit"); variables.put("numberOfDays", new Integer(4)); variables.put("vacationMotivation", "I'm really tired!"); RuntimeService runtimeService = processEngine.getRuntimeService(); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("vacationRequest", variables); // Verify that we started a new process instance Log.info("Number of process instances: " + runtimeService.createProcessInstanceQuery().count());
Complete the task
- After the process starts, the first step is the user task This is a link that must be handled by the system user
- The user will have a "task list" showing all the tasks that must be handled by the whole user The following is the corresponding query:
-
// Fetch all tasks for the management group TaskService taskService = processEngine.getTaskService(); List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("management").list(); for (Task task : tasks) { Log.info("Task available: " + task.getName()); }
Task task = tasks.get(0); Map<String, Object> taskVariables = new HashMap<String, Object>(); taskVariables.put("vacationApproved", "false"); taskVariables.put("managerMotivation", "We have a tight deadline!"); taskService.complete(task.getId(), taskVariables);
- Then the process instance will move to the next step
- The next step allows employees to adjust the original leave application through the form The employee can resubmit the leave application, which will bring the process back to the first task
Suspend or activate a process
- You can suspend a process definition. When you suspend a process definition, you cannot create a new process, and an exception will be thrown You can suspend a process through the repository service:
repositoryService.suspendProcessDefinitionByKey("vacationRequest"); try { runtimeService.startProcessInstanceByKey("vacationRequest"); } catch (ActivitiException e) { e.printStackTrace(); }
- To reactivate a process definition, you can call repositoryservice Activateprocessdefinitionxxx method
- You can also suspend a process instance:
- When suspended, the process cannot continue to execute: for example, exceptions will be thrown when the task is completed, and asynchronous operations (such as timers) will not be executed A suspended process instance can call runtimeservice Suspendprocessinstance method
- Activate the process instance and call runtimeservice Activateprocessinstancexxx method
Click focus to learn about Huawei cloud's new technologies for the first time~