This is the 10th day of my participation in the August Text Challenge.More challenges in August
An Activiti workflow introduction
1 overview Activiti
1.1 Activiti
Activiti is a workflow engine that extracts complex business processes from business systems and uses BPMN2.0 to define them. Business processes are executed according to predefined processes. Activiti manages the process flow of the system and reduces the amount of work required to upgrade a business system due to process changes In order to improve the robustness of the system, but also reduce the cost of system development and maintenance.
1.2 BPM
BPM(Business Process Management) : Business Process Management is a systematic method centering on the standardized construction of end-to-end excellent Business processes and aiming at continuously improving the Business performance of organizations. Common Business Management, such as EMBA/MBA, includes BPM.
BPM software: IT tools that promote the integration and adjustment of business methods and solutions among people, between people and systems, and between systems, according to the changing business environment in the enterprise.
BPMN(Business Process Model And Notation) : The Business Process Model And Notation, which is provided by BPMI(Business Process Management Initiative). Developed a standard set of business process modeling notations that can be used to create business processes using notations provided by BPMN.
1.3 Introduction to BPMN symbols
1, represented by a circle, is what happens when the process runs.
Activities are represented by rounded rectangles. A process consists of one or more activities.
Tips: A BPMN graph is simply an XML representation of a business process, opened with a text editor and containing an XML file.
2 How to use Activiti
1 deployment Activiti
Activiti is a workflow engine (JAR package API) that enables business systems to access Activiti’s interface to easily manipulate process-related data and integrate workflow and business environments.
2 Process Definition
Define business processes (BPMN files) using the Activiti process Modeling tool (Acitivity Designer).
3 Route definition deployment
Activiti deploys the business process definition, stores the process definition content using the API provided by Activiti, and stores the process definition content in the database during Activiti execution.
4 Start a process instance
ProcessInstance :ProcessInstance, starting a ProcessInstance starts the running of a business process.
After the definition and deployment of employee leave process is completed, Zhang SAN asks for leave to start a process instance, li Si asks for leave to start a process instance, and the execution of the two processes does not interfere with each other.
5 Query the to-do task
Use Activiti to query where the current process is and what tasks the current user needs to perform.
6 Perform tasks
A user can perform a task after querying a to-do task.
7 Process End
When a task is completed and there is no next task node, the process instance is complete.
Two Activiti environment
1 Development Environment
Jdk1.8 / Mysql 5 / Tomcat8.5 / IDEA
Activiti7.0.0.Beta1(Spring5 is supported by default, note the number 1 after Beta)
2 prepare Activiti7
1 Download from the official website. activiti.org/download.ht…
2 Import coordinates in Maven
<dependencies> <! <dependency> <groupId>org.activiti</groupId> <artifactId> Activiti -engine</artifactId> < version > 7.0.0. Beta1 < / version > < / dependency > < / dependencies >Copy the code
3 Activiti database support
1 Activiti supports databases
2 Generate a table in Mysql
1 create database activiti(database name arbitrary)
CREATE DATABASE activiti DEFAULT CHARACTER SET utf8;
Copy the code
2 Create a Java project
Use IDEA to create a Java Maven project named Activiti-Demo
3 Import maven coordinates
1 the pom. XML file
<! -- Current project code and JDK version -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<activiti.version>7.0.0. Walk</activiti.version>
</properties>
<dependencies>
<! - a core -- > activiti
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti.version}</version>
</dependency>
<! -- BPMN model processing -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>${activiti.version}</version>
</dependency>
<! - BPMN translation -- -- >
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<! -- BPMN json data conversion -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<! BPMN layout -- -- - >
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti.version}</version>
</dependency>
<! -- Activiti Cloud support -->
<dependency>
<groupId>org.activiti.cloud</groupId>
<artifactId>activiti-cloud-services-api</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.5.4</version>
</dependency>
<! - mysql driver - >
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.40</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
<! --mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.5</version>
</dependency>
<! -- Connection pool -->
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<! --log start-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.16</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.0.8. RELEASE</version>
</dependency>
</dependencies>
Copy the code
2 log4j.properties
log4j.rootLogger=debug, CONSOLE, LOGFILE
log4j.logger.org.apache.axis.enterprise=fatal, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8610} % -6r [%15.15t] %-5p %30.30.c %c - %m\n
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=d:\act\activiti.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8610} % -6r [%15.15t] %-5p %30.30.c %c - %m\n
Copy the code
4 Activiti profile
To create mysql tables using the default method provided by Activiti, you need to create the activiti.cfg. XML file in the Resources directory (the location of the file and the name of the file cannot be changed).
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/activiti"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<! SQL > create a table that does not exist in the database
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
Copy the code
5 Create test classes and generate tables
@Test
public void testCreateDbTable(a) {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
System.out.println(processEngine);
}
Copy the code
6 Table structure
Classification table | The name of the table | explain |
---|---|---|
General data | ||
ACT_GE_BYTEARRAY | Common process definitions and process resources | |
ACT_GE_PROPERTY | System related Attributes | |
Process history | ||
ACT_HI_ACTINST | Historical process instances | |
ACT_HI_ATACHMENT | Historical process attachments | |
ACT_HI_COMMENT | Historical illustrative information | |
ACT_HI_DETAIL | Details of the process execution in history | |
ACT_HI_IDENTITYLINK | History of user relationships during process runs | |
ACT_HI_PROCINST | Historical process instances | |
ACT_HI_TASKINST | Historical task instances | |
ACT_HI_VARINST | Historical information about variables in a process run | |
Process definition table | ||
ACT_RE_DEPLOYMENT | Deployment Unit Information | |
ACT_RE_MODEL | Model information | |
ACT_RE_PROCDEF | Deployed process definitions | |
Run instance table | ||
ACT_RU_EVENT_SUBSCR | Run time event | |
ACT_RU_EXECUTION | Runtime process execution instance | |
ACT_RU_IDNTITYLINK | Runtime user relationship information, which stores information about task nodes and participants | |
ACT_RU_JOB | Run time job | |
ACT_RU_TASK | Runtime task | |
ACT_RU_VARIABLE | Run time varying meter |
Three Activiti class diagrams
Class 1 diagram
In the new version dentityService FormService two Service has been deleted.
2 activiti.cfg.xml
The activiti engine configuration files, including the definition of the ProcessEngineConfiguration, data source definition, transaction management, etc., similar to a spring configuration file.
3 Process engine configuration class
Process engine configuration class (ProcessEngineConfiguration) through the configuration class can create a workflow engine ProcessEngine.
1 StandaloneProcessEngineConfiguration
Use this class to create ProcessEngine, and Activiti will handle the transaction itself. (Optimization: Data sources can use connection pooling.)
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/activiti"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<! SQL > create a table that does not exist in the database
<property name="databaseSchemaUpdate" value="true"/>
</bean>
Copy the code
2 SpringProcessEngineConfiguration
Integrate with Spring, use this class, configure transactions, and let Spring manage them
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/activiti"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="maxActive" value="3"/>
<property name="maxIdle" value="1"/>
</bean>
<! -- Transaction manager -->
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
<! -- Data source -->
<property name="dataSource" ref="dataSource"/>
<! -- Spring Transaction Management -->
<property name="transactionManager" ref="transactionManager"/>
<! -- Database policy -->
<property name="databaseSchemaUpdate" value="drop-create"/>
</bean>
<! -- Process Engine -->
<bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
<property name="processEngineConfiguration" ref="processEngineConfiguration"/>
</bean>
Copy the code
4 Create a workflow engine
Workflow engine (ProcessEngine), equivalent to a facade interface, through the ProcessEngineConfiguration create ProcessEngine, create the Service through ProcessEngine interface.
1 Default creation mode
Fixed activiti. CFG. XML file name and path, and activiti ProcessEngineConfiguration configuration file, you can use ProcessEngines tools directly created
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Copy the code
2 Common creation mode
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine processEngine = configuration.buildProcessEngine();
Copy the code
5 Service Indicates the Service interface
A Service is a Service interface provided by a workflow engine for workflow deployment, execution, and management. We can use these interfaces to operate the corresponding data tables of the Service.
1 Service creation mode
Create the Service from ProcessEngine
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
TaskService taskService = processEngine.getTaskService();
HistoryService historyService = processEngine.getHistoryService();
Copy the code
2 Service Function description
The name of the service | The service function |
---|---|
RepositoryService | Activiti’s resource management class |
RuntimeService | Activiti’s process run management class |
TaskService | Activiti’s task management class |
HistoryService | Activiti’s history management class |
ManagerService | Activiti’s engine management class |
Four Activiti get started
Steps to create a workflow:
- Define the process: According to BPMN, use the process definition tool to describe the entire process in process notation.
- Deploy process: load the drawn process definition file into the database to generate table data.
- Startup process: Use Java code to manipulate table contents in a database
1 Process Notation (BPMN2.0)
Events in the Event
Activity Activiti
The Gateway of Gateway
[ImG-NYg300VC-1610808984400] (assets/image-20210116172335147.png)
Flow to the Flow
2. Use of process designer
Install the actBPM plug-in in IDEA and create a BPMN file
Design a leave process
2 Assign a task manager
3 Generate a PNG file
1 Copy the BPMN file and change the suffix to XML
2 Perform the following operations to obtain a PNG image and save the image
3 Activiti Start operations
1 Process Deployment
/** * Test process deployment */
@Test
public void testDeployment(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RepositoryService / / 2
RepositoryService repositoryService = processEngine.getRepositoryService();
//3 Use service to deploy the process, define a process name, and deploy BPMN and PNG to the data
Deployment deploy = repositoryService.createDeployment()
.name("Business Trip Application Process")
.addClasspathResource("bpmn/evection.png")
.addClasspathResource("bpmn/evection.bpmn")
.deploy();
//4 Output deployment information
System.out.println(deploy.getId() + "Process Deployment ID");
System.out.println(deploy.getName() + "Process Deployment name");
}
Copy the code
Conclusion:
1 use flow designer, use flow symbol, draw flow chart
BPMN file, PNG file
Are process resource files that describe the nodes and node owners needed in the process
Business trip application process, leave application process, reimbursement application process…
2 Deploy the resource file of the process
Upload to the database and deploy the process using Java code
One deployment operation:
ACT_RE_DEPLOYMENT generates a record
ACT_RE_PROCDEF generates process definition information
One-to-many relationship between 3 Deployment and procdef table
There can be multiple records in the procDEF table, each of which corresponds to the definition information of a process
2 Start the process instance
/** * Start the process instance */
@Test
public void teststartProcess(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RuntimeService / / 2
RuntimeService runtimeService = processEngine.getRuntimeService();
//3 Start the process based on the id defined by the process
String processInstanceByKey = "myEvection";
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processInstanceByKey);
//4 Output content
System.out.println(processInstance.getProcessDefinitionId() + "Process instance ID");
System.out.println(processInstance.getId() + "Process instance ID");
System.out.println(processInstance.getActivityId() + "Current active ID");
}
Copy the code
3 personal task query
/** * Personal task query */
@Test
public void testFindPersonTaskList(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get TaskService / / 2
TaskService taskService = processEngine.getTaskService();
//3 Query tasks based on the flow key and task owner
String assignee = "zhangsan";
String definitionKey = "myEvection";
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey(definitionKey)/ / process the key
.taskAssignee(assignee)// The person in charge of the query
.list();
//4 Output content
for (Task task : taskList) {
System.out.println(task.getProcessDefinitionId() + "Id of the current task instance");
System.out.println(task.getId() + "Current task ID");
System.out.println(task.getName() + "Name of current task");
System.out.println(task.getAssignee() + "The person in charge of the current task."); }}Copy the code
Complete 4 personal missions
/** * Complete personal missions */
@Test
public void completTask(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get TaskService / / 2
TaskService taskService = processEngine.getTaskService();
//3 Complete the task based on the task ID
/* String taskId = "2505"; taskService.complete(taskId); * /
//4 Get personal tasks based on the delegate and instance key
String definitionKey = "myEvection";
String assignee = "rose";
Task task = taskService.createTaskQuery()
.processDefinitionKey(definitionKey)// Process instance key
.taskAssignee(assignee)// Assignment person
.singleResult();// Single result
taskService.complete(task.getId());
System.out.println("Mission accomplished.");
}
Copy the code
5 Deploy the flow in ZIP mode
/** * Deploy */ in zip mode
@Test
public void testZipDeployment(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RepositoryService / / 2
RepositoryService repositoryService = processEngine.getRepositoryService();
//3 Use service to deploy the process, define a process name,zip deployment
InputStream inputStream = this.getClass()
.getClassLoader()
.getResourceAsStream("bpmn/bpmn.zip");
System.out.println(inputStream);
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
Deployment deploy = repositoryService
.createDeployment()// Create deployment
.addZipInputStream(zipInputStream)// Add the zip input stream
.name("Leave Procedures")// Process name
.key("myEvection")The key / / instance
.deploy();
//4 Output deployment information
System.out.println(deploy.getId() + "Process Deployment ID");
System.out.println(deploy.getName() + "Process Deployment name");
}
Copy the code
5 Process Operation
1 Process definition Information query
/** * Query process definition */
@Test
public void queryProcessDefinition(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RepositoryService / / 2
RepositoryService repositoryService = processEngine.getRepositoryService();
ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
String key = "myEvection";
List<ProcessDefinition> definitionList = definitionQuery.processDefinitionKey(key)
.orderByProcessDefinitionVersion()
.desc()
.list();
for (ProcessDefinition processDefinition : definitionList) {
System.out.println("Process Definition ID" + processDefinition.getId());
System.out.println("Process Definition Name" + processDefinition.getName());
System.out.println("Process definition Key" + processDefinition.getKey());
System.out.println("Process Definition Deployment ID" + processDefinition.getDeploymentId());
System.out.println("Process Definition Version Number"+ processDefinition.getVersion()); }}Copy the code
2 Process Deletion
/** * Process definition deleted */
@Test
public void deleteDeployMent(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RepositoryService / / 2
RepositoryService repositoryService = processEngine.getRepositoryService();
String deployMentId = "15001"; repositoryService.deleteDeployment(deployMentId); * /
/** * Delete process deployment information ** If the current process is not completed, you need to delete it in a special way. The principle is cascading deletion */
String deployMentId = "1";
repositoryService.deleteDeployment(deployMentId, true);
System.out.println("Deleted successfully");
}
Copy the code
3 Download flow resources
/** * Download the file from Activiti. /** * Download the file from Activiti. /** * Download the file from Activiti. ** * Download the file from Activiti. commons-io.jar */
@Test
public void getDeployment(a) throws IOException {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RepositoryService / / 2
RepositoryService repositoryService = processEngine.getRepositoryService();
//3 Obtain the query object and process definition information
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("myEvection")
.singleResult();
//4 Obtain the deployment ID based on the flow definition information
String deploymentId = processDefinition.getDeploymentId();
//5 Obtain the resource information (PNG and BPMN) by RepositoryService.
/ / 5.1 PNG
// From the process definition table, get the directory and name of the PNG image
String pngName = processDefinition.getDiagramResourceName();
InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, pngName);
/ / get the BPMN 5.2
String bpmnName = processDefinition.getResourceName();
InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, bpmnName);
//6 Construct the OutputStream
File pngFile = new File("d/evection.png");
File bpmnFile = new File("d/evection.bpmn");
FileOutputStream pngOutStream = new FileOutputStream(pngFile);
FileOutputStream bpmnOutStream = new FileOutputStream(bpmnFile);
//7 Input stream, output stream conversion
IOUtils.copy(bpmnInput, bpmnOutStream);
IOUtils.copy(pngInput, pngOutStream);
/ / 8 shut down stream
bpmnOutStream.close();
pngOutStream.close();
bpmnInput.close();
pngInput.close();
}
Copy the code
4 Viewing historical flow information
/** * View historical information */
@Test
public void findHistoryInfo(a) {
// Get the engine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/ / get HistoryService
HistoryService historyService = processEngine.getHistoryService();
// Obtain the query object of the actinst table
HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
// query the actinst table
//1 Query using the process instance ID
//2 Use the process to define the ID query
// String processInstanceId = "7501";
String processDefinitionId = "myEvection:1:5004";
List<HistoricActivityInstance> list = historicActivityInstanceQuery
// .processInstanceId(processInstanceId)
.processDefinitionId(processDefinitionId)
.orderByHistoricActivityInstanceStartTime()
.asc()
.list();
/ / output
for (HistoricActivityInstance instance : list) {
System.out.println(instance.getActivityId()+"The activity id");
System.out.println(instance.getActivityName()+"Activity Name");
System.out.println(instance.getProcessDefinitionId()+"Define id");
System.out.println(instance.getProcessInstanceId()+"Instance id");
System.out.println("= = = = = = = = = = = = = = = ="); }}Copy the code
Six Process Examples
ProcessInstance represents the execution instance of the process definition.
A process instance contains all running nodes.
2 Start the process instance and add Businesskey
/** * Add a business key to the Activiti table */
@Test
public void addBusinessKey(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RuntimeService / / 2
RuntimeService runtimeService = processEngine.getRuntimeService();
//3 Add businessKey during the start process
String processDefinitionKey = "myEvection";
String businessKey = "1001";
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey(processDefinitionKey, businessKey);
System.out.println("businessKey : " + processInstance.getBusinessKey());
}
Copy the code
Suspend and activate process definitions
The process can proceed downward only when it is activated, that is, the task handler can complete the task; The pending task could not be completed
Full suspension and activation defined by the process
/** * Suspend and activate all processes */
@Test
public void suspendAllProcessInstance(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RepositoryService / / 2
RepositoryService repositoryService = processEngine.getRepositoryService();
//3 Query the flow definition and obtain the query object of the flow definition
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("myEvection")
.singleResult();
//4 Gets whether the instance of the current process definition is in the pending state
boolean suspended = processDefinition.isSuspended();
//5 Get the id of the process definition
String definitionId = processDefinition.getId();
if (suspended) {
//6 Operation parameters that can be activated in the hang up state 1: process definition ID 2: Activation parameter 3: activation time
repositoryService.activateProcessDefinitionById(definitionId,
true.null);
System.out.println("Process definition ID:" + definitionId + "Active");
} else {
Parameter 1: process definition ID parameter 2: Activation parameter 3: activation time parameter
repositoryService.suspendProcessDefinitionById(definitionId,
true.null);
System.out.println("Process definition ID:" + definitionId + "Suspended"); }}Copy the code
Suspend and activate a single process
/** * Suspend and activate a single process */
@Test
public void suspendProcessInstance(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RepositoryService / / 2
RuntimeService runtimeService = processEngine.getRuntimeService();
//3 Query the flow definition and obtain the query object of the flow definition
String processInstanceId = "10001";
ProcessInstance processInstance = runtimeService
.createProcessInstanceQuery()
.processInstanceId(processInstanceId)
.singleResult();
//4 Gets whether the instance of the current process definition is in the pending state
boolean suspended = processInstance.isSuspended();
//5 Get the id of the process definition
String InstanceId = processInstance.getId();
if (suspended) {
//6 Operation parameters that can be activated in the hang up state 1: process definition ID 2: Activation parameter 3: activation time
runtimeService.activateProcessInstanceById(InstanceId);
System.out.println("Process instance ID:" + InstanceId + "Active");
} else {
Parameter 1: process definition ID parameter 2: Activation parameter 3: activation time parameter
runtimeService.suspendProcessInstanceById(InstanceId);
System.out.println("Process instance ID:" + InstanceId + "Suspended"); }}Copy the code
Seven-man mission
1. Assign responsible person
1 Fixed allocation
2 Expression allocation
Activiti uses UEL expressions. UEL is part of the Java EE6 specification. UEL(Unified Expression Language) supports two UEL expressions: UEL-Value and UEL-Method
1UEL-value
2UEL-method
3 Uel-value and Uel-method are combined
${userService.findAll (emp)} UserService is a bean in the Spring container,findAll is a process variable in the bean, and emP is passed to the findAll method as a parameter.
4 other
Expressions support parsing of basic types, beans, lists, arrays, maps, and conditional judgments.
${order.price>100 && order.price<200}
/** * Start process */
@Test
public void teststartProcess(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RuntimeService / / 2
RuntimeService runtimeService = processEngine.getRuntimeService();
//3 Start the process based on the id defined by the process
String processInstanceByKey = "evection-global";
Map<String, Object> variablesMap = new HashMap<>();
variablesMap.put("assignee0"."Zhang");
variablesMap.put("assignee1"."Bill");
variablesMap.put("assignee2"."Fifty");
variablesMap.put("assignee3"."Daisy");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processInstanceByKey, variablesMap);
//4 Output content
System.out.println(processInstance.getProcessDefinitionId() + "Process instance ID");
System.out.println(processInstance.getId() + "Process instance ID");
System.out.println(processInstance.getActivityId() + "Current active ID");
}
Copy the code
3 Listener assignment
public class MyTaskListen implements TaskListener {
/** * use the listener to specify the task manager *@param delegateTask
*/
@Override
public void notify(DelegateTask delegateTask) {
// Check whether the application is created
if ( "Travel Application".equals(delegateTask.getName()) && "create".equals(delegateTask.getEventName())) {
// Assign a task manager
delegateTask.setAssignee("Zhang");
}else {
delegateTask.setAssignee("Bill"); }}}Copy the code
2 Query Task
/** * Personal task query */
@Test
public void testFindPersonTaskList(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get TaskService / / 2
TaskService taskService = processEngine.getTaskService();
//3 Query tasks based on the flow key and task owner
String assignee = "zhangsan";
String definitionKey = "myEvection";
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey(definitionKey)/ / process the key
.taskAssignee(assignee)// The person in charge of the query
.list();
//4 Output content
for (Task task : taskList) {
System.out.println(task.getProcessDefinitionId() + "Id of the current task instance");
System.out.println(task.getId() + "Current task ID");
System.out.println(task.getName() + "Name of current task");
System.out.println(task.getAssignee() + "The person in charge of the current task."); }}Copy the code
3 Task Management
/** * Complete personal missions */
@Test
public void completTask(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get TaskService / / 2
TaskService taskService = processEngine.getTaskService();
//3 Complete the task based on the task ID
/* String taskId = "2505"; taskService.complete(taskId); * /
//4 Get personal tasks based on the delegate and instance key
String definitionKey = "myEvection";
String assignee = "rose";
Task task = taskService.createTaskQuery()
.processDefinitionKey(definitionKey)// Process instance key
.taskAssignee(assignee)// Assignment person
.singleResult();// Single result
taskService.complete(task.getId());
System.out.println("Mission accomplished.");
}
Copy the code
Viii. Flow Variables
1 What are process variables
Process variables: Variables that Activiti sets for administrative purposes when managing workflow
2 Process variable type
3 Process variable scope
The scope of a process variable can be a process instance, a task, or an execution instance.
A global variable
The default scope of a process variable is a process instance, and when a process variable is scoped to a process instance, it can be called a global variable.
The variable name in the global variable cannot be the same. If you set a variable with the same name, the later value overwrites the previous value.
2 the local variable
Tasks and execution instances are only for a task and an execution instance scope, which is not as large as the process instance and is called the local variable.
4. Use of process variables
Use UEL expressions on attributes
Set UEL expressions at assignee, such as ${assignee}
Use UEL expressions on wires
Such as ${100} price <
5 Use Global variables to control the flow
1 Create a POJO object
/ / entity class
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Evection implements Serializable {
private Long id;
private String evectionName;
private Double num;
private Date beginTime;
private Date endTime;
private String reason;
private String desraption;
}
Copy the code
2 Set variables when starting the process
/** * Start process */
@Test
public void teststartProcess(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get RuntimeService / / 2
RuntimeService runtimeService = processEngine.getRuntimeService();
//3 Start the process based on the id defined by the process
String processInstanceByKey = "evection-global";
// Specify the connection conditions
Evection evection = new Evection();
evection.setNum(3.0);
Map<String, Object> variablesMap = new HashMap<>();
variablesMap.put("evection", evection);
// Assign a task person
variablesMap.put("assignee0"."Zhang");
variablesMap.put("assignee1"."Bill");
variablesMap.put("assignee2"."Fifty");
variablesMap.put("assignee3"."Daisy");
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processInstanceByKey, variablesMap);
//4 Output content
System.out.println(processInstance.getProcessDefinitionId() + "Process instance ID");
System.out.println(processInstance.getId() + "Process instance ID");
System.out.println(processInstance.getActivityId() + "Current active ID");
}
Copy the code
3 Set variables during task handling
@Test
public void completTask(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get TaskService / / 2
TaskService taskService = processEngine.getTaskService();
//3 Complete the task based on the task ID
String definitionKey = "myEvection";
String assignee = "zhangsan";
String processInstanceId = "10001";
Task task = taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.taskAssignee(assignee)
.singleResult();
// Set variables
Map<String, Object> variablesMap = new HashMap<>();
variablesMap.put("assignee0"."Zhang");
variablesMap.put("assignee1"."Bill");
variablesMap.put("assignee2"."Fifty");
variablesMap.put("assignee3"."Daisy");
taskService.complete(task.getId(),variablesMap);
}
Copy the code
4 Set parameters based on the current flow instance
@Test
public void setGlobalVariableByExecutionId(a) {
// Current process instance execution ID, usually set to the currently executing process instance
String executionId = "2601";
/ / create a ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/ / get RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3 Create a travel POJO object
Evection evection = new Evection();
// Set the days
evection.setNum(3d);
// Set the process variable with the process instance id
runtimeService.setVariable(executionId,"evection",evection);
// Set multiple values at once
// runtimeService.setVariable(executionId,variables);
}
Copy the code
5 Set the current task
@Test
public void setGlobalVariableByTaskId(a) {
// Id of the current to-do task
String taskId = "2601";
/ / create a ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/ / get the TaskService
TaskService taskService = processEngine.getTaskService();
//3 Create a travel POJO object
Evection evection = new Evection();
// Set the days
evection.setNum(3d);
// Set the process variable with the process instance id
taskService.setVariable(taskId,"evection",evection);
// Set multiple values at once
// taskService.setVariable(taskId,variables);
}
Copy the code
6 Set the local variable
1 Set during task handling
@Test
public void completTask(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get TaskService / / 2
TaskService taskService = processEngine.getTaskService();
//3 Complete the task based on the task ID
String definitionKey = "myEvection";
String assignee = "zhangsan";
String processInstanceId = "10001";
Task task = taskService.createTaskQuery()
.processInstanceId(processInstanceId)
.taskAssignee(assignee)
.singleResult();
// Set variables
Map<String, Object> variablesMap = new HashMap<>();
variablesMap.put("assignee0"."Zhang");
variablesMap.put("assignee1"."Bill");
variablesMap.put("assignee2"."Fifty");
variablesMap.put("assignee3"."Daisy");
// Set the local variable scoped to the task
taskService.setVariablesLocal(taskId,variables);
// Complete the task
taskService.complete(task.getId());
}
Copy the code
2 Use the current Settings
@Test
public void setGlobalVariableByTaskId(a) {
// Id of the current to-do task
String taskId = "2601";
/ / create a ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/ / get the TaskService
TaskService taskService = processEngine.getTaskService();
//3 Create a travel POJO object
Evection evection = new Evection();
// Set the days
evection.setNum(3d);
// Set the process variable with the process instance id
taskService.setVariableLocal(taskId,"evection",evection);
// Set multiple values at once
// taskService.setVariableLocal(taskId,variables);
}
Copy the code
9 set of tasks
1 group task handling process
A Query group tasks
To query the current to-do list of a specified candidate. Candidates are not able to take on assignments immediately
B Pick-up task
All candidates in this group of tasks can be picked.
Turn a candidate’s group task into an individual task, and the original candidate becomes the person in charge of that task.
If you don’t want to handle it after picking up? The individual task becomes the group task when the task is returned to the group task.
C Query personal tasks
The individual task part of bucket query mode is based on the individual task responsible by assignee query user.
2 Query group tasks
@Test
public void findGroupTaskList(a) {
// The process defines the key
String processDefinitionKey = "evection3";
// Task candidate
String candidateUser = "lisi";
/ / create a ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/ / get the TaskService
TaskService taskService = processEngine.getTaskService();
// Query group tasks
List<Task> list = taskService.createTaskQuery()
.processDefinitionKey(processDefinitionKey)
.taskCandidateOrAssigned(candidateUser)
.list();
for (Task task : list) {
System.out.println("= = = = = = = = = = = = = = = = = = = = = = = = = = = = = =");
System.out.println(task.getProcessDefinitionId() + "Id of the current task instance");
System.out.println(task.getId() + "Current task ID");
System.out.println(task.getName() + "Name of current task");
System.out.println(task.getAssignee() + "The person in charge of the current task."); }}Copy the code
3 Pick up group tasks
@Test
public void claimTask(a) {
/ / create a ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/ / get the TaskService
TaskService taskService = processEngine.getTaskService();
// To pick up the task ID
String taskId = "6302";
String userId = "lisi";
// Query group tasks
Task task= taskService.createTaskQuery()
.taskId(taskId)
.taskCandidateUser(userId)
.singleResult();
if(task ! =null) {// Pick task
taskService.claim(taskId,userId);
System.out.println("Task pickup completed"); }}Copy the code
4 Query the personal to-do list
/** * Personal task query */
@Test
public void testFindPersonTaskList(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get TaskService / / 2
TaskService taskService = processEngine.getTaskService();
//3 Query tasks based on the flow key and task owner
String assignee = "zhangsan";
String definitionKey = "myEvection";
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey(definitionKey)/ / process the key
.taskAssignee(assignee)// The person in charge of the query
.list();
//4 Output content
for (Task task : taskList) {
System.out.println(task.getProcessDefinitionId() + "Id of the current task instance");
System.out.println(task.getId() + "Current task ID");
System.out.println(task.getName() + "Name of current task");
System.out.println(task.getAssignee() + "The person in charge of the current task."); }}Copy the code
Handling personal business
/** * Complete personal missions */
@Test
public void completTask(a) {
Create ProcessEngine / / 1
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Get TaskService / / 2
TaskService taskService = processEngine.getTaskService();
//3 Complete the task based on the task ID
String taskId = "2505";
taskService.complete(taskId);
System.out.println("Mission accomplished.");
}
Copy the code
6 Return group tasks
@Test
public void setAssigneeToGroupTask(a) {
/ / create a ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/ / get the TaskService
TaskService taskService = processEngine.getTaskService();
// To pick up the task ID
String taskId = "6004";
String userId = "zhangsan";
// Query group tasks
Task task= taskService.createTaskQuery()
.taskId(taskId)
.taskAssignee(userId)
.singleResult();
if(task ! =null) {// If set to null, return the group task, otherwise the task has no owner
taskService.setAssignee(taskId,null); }}Copy the code
7 Task Handover
@Test
public void setAssigneeToCandidateUser(a) {
/ / create a ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/ / get the TaskService
TaskService taskService = processEngine.getTaskService();
// To pick up the task ID
String taskId = "6004";
String userId = "zhangsan";
// Assign tasks to other candidates
String candidateuser = "zhangsan";
// Query group tasks
Task task= taskService.createTaskQuery()
.taskId(taskId)
.taskAssignee(userId)
.singleResult();
if(task ! =null) {// If set to null, return the group task, otherwise the task has no ownertaskService.setAssignee(taskId,candidateuser); }}Copy the code
Ten gateway
1 ExclusiveGate
The exclusive gateway is used to implement decisions in the process, and when the process executes to this gateway, all branches determine whether the condition is true and execute the branch if true.
2 ParallelGateway
Parallel gateways allow a process to be split into multiple branches and to be brought together. The functions of parallel gateways are based on incoming and outgoing sequential flows:
- Fork: All outgoing sequential streams after parallel, creating a concurrent branch for each sequential stream
- Join convergence: All branches that reach the parallel gateway wait to enter the branch until all branches that enter the sequential flow are reached and the process passes through the convergence gateway.
All incoming sequential streams are then sliced into parallel branches.
The main difference from other gateways is that parallel gateways do not parse conditions, and even if conditions are defined in sequential flows, they are ignored.
3 InclusiveGateway
Include gateway can be seen as a combination of a work – exclusive gateway and a parallel gateway. As with exclusive gateways, you can define conditions on outgoing sequential streams, and the inclusion gateway will resolve them, but the main difference is that the inclusion gateway can select more than one sequential stream, as with the parallel gateway.
Includes gateways:
- Branching: All conditions of the outgoing sequence stream are resolved, and the sequence stream that results in true continues execution in parallel, creating a branch for each sequence stream.
- Convergence: All parallel branches reach the gateway and enter a wait state until each branch that enters the sequential flow containing the process token is reached. The include gateway simply waits for incoming sequential flows to be selected for execution, and after convergence, the process continues through the include gateway.
** Summary: when ** branches, it is necessary to judge the conditions. The branches that meet the conditions will be executed, and the branches that meet the conditions will finally be aggregated.
4 EventGateway
Event gateway: Each outgoing order of the gateway is connected to an intermediate capture event based on the direction of the event. When the process reaches an event-based gateway, the gateway enters a wait state and pauses execution while a relative event subscription is created for each outgoing sequential flow.