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.