The most complete Activiti learning tutorial in history, and the most powerful workflow engine in one article!

1. Workflow Introduction

1.1 Concept

Workflow is to automate the management of business processes through computers. It mainly solves "the process of automatically transferring documents, information or tasks among multiple participants according to some predefined rules, so as to achieve a certain expected business goal, or promote the realization of this goal."

1.2 Workflow system

A software system has the function of workflow, we call it a workflow system, what is the function of workflow in a system? It is to automate the management of the business process of the system, so the workflow is based on the business process, so the core of a software system is basically the business process of the system, and the workflow is only to assist in the management of the business process. Even if there is no workflow business system, it can be developed and run, but with workflow, business processes can be better managed and the scalability of the system can be improved.

1.3 Applicable industries

Consumer goods industry, manufacturing industry, telecommunications service industry, financial service industry such as bank securities insurance, logistics service industry, property service industry, property management, large and medium-sized import and export trading companies, government institutions, research institutes and education service industries, etc., especially It is a large multinational enterprise and group company.

1.4 specific application

1. Key business processes: order, quotation processing, contract review, customer call processing, supply chain management, etc.

2. Administrative management: business trip applications, overtime applications, leave applications, car applications, various office supplies applications, purchase applications, daily and weekly reports, etc. All administrative forms that were originally processed manually.

3. Personnel management: employee training arrangement, performance appraisal, job change processing, employee file information management, etc.

4. Financial related categories: payment request, receivables processing, daily reimbursement processing, business trip reimbursement, budget and plan application, etc.

5. Customer service category: customer information management, customer complaints, request processing, after-sales service management, etc.

6. Special service categories: ISO series corresponding processes, quality management corresponding processes, product data information management, customs declaration processing for trading companies, cargo tracking processing for logistics companies, etc., can be automatically standardized by workflow software for various tasks that are completed gradually and manually through forms. implemented.

1.5 Implementation

Before there was a dedicated workflow engine, in order to achieve process control, we usually used the value of the status field to track the change of the process. In this way, users with different roles decide whether to display the record through the value of the status field.

For the records that can be viewed with permission, the current user decides whether to approve the qualified operation according to his role. If qualified, set a value in the status field to represent qualified; of course, if unqualified, a value also needs to be set to represent unqualified.

This is the most primitive way. Although the process control is achieved through the status field, when our process changes, the code written in this way must also be adjusted.

So is there a professional way to achieve workflow management? And it can be achieved that after the business process changes, our program does not need to be changed. If this effect can be achieved, then the adaptability of our business system will be greatly improved.

Recommend an open source and free Spring Boot most complete tutorial:

https://github.com/javastacks/spring-boot-best-practice

2. Overview of Activiti7

2.1 Introduction

Alfresco Software announced the official launch of the Activiti business process management (BPM) open source project on May 17, 2010. Its chief architect is Tom Baeyens, an expert in business process management BPM. Tom Baeyens is the architect of the original jbpm, and jbpm is A very famous workflow engine, of course activiti is also a workflow engine.

Activiti is a workflow engine. Activiti can extract the complex business processes in the business system and define them using the special modeling language BPMN2.0. The business processes are executed according to the predefined processes, and the system processes are implemented by Activiti. Management, reducing the workload of business systems for system upgrading and transformation due to process changes, thereby improving the robustness of the system and reducing system development and maintenance costs.

Official website: https://www.activiti.org/

Experienced version:

The latest version: Activiti7.0.0.Beta

2.1.1 BPM

BPM (Business Process Management), that is, business process management, is a standardized construction of end-to-end business processes to continuously improve organizational business efficiency. BPM is included in common business management education such as EMBA and MBA.

2.1.2 BPM software

BPM software is an IT tool that promotes the integration and adjustment of business methods and solutions between people, between people and systems, and between systems according to changes in the business environment in the enterprise.

Modeling, automation, management monitoring and optimization of the entire life cycle of the internal and external business processes of the enterprise through BPM software can reduce the cost of the enterprise and greatly increase the profit.

BPM software is widely used in enterprises. Wherever there are business processes, BPM software can be used for management, such as enterprise personnel office management, procurement process management, official document approval process management, financial management, etc.

2.1.3 BPMN

BPMN (Business Process Model And Notation) - business process model and notation is a set of standard business process modeling notations developed by BPMI (BusinessProcess Management Initiative), and business processes can be created using the notations provided by BPMN.

The BPMN1.0 specification was released in May 2004. BPMI was incorporated into the OMG (The Object Management Group) organization in September 2005. OMG released the final version of BPMN2.0 in January 2011.

The specific development history is as follows:

BPMN is currently a BPM standard widely accepted by various BPM vendors. Activiti uses BPMN 2.0 for process modeling and process execution management. It includes many modeling symbols, such as: Event

Represented by a circle, it's something that happens during the run of the process.

Activities are represented by rounded rectangles, and a process consists of one activity or multiple activities

The Bpmn graph actually represents the business process through xml, and the .bpmn file above is opened with a text editor:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
  <process id="myProcess" name="My process" isExecutable="true">
    <startEvent id="startevent1" name="Start"></startEvent>
    <userTask id="usertask1" name="创建请假单"></userTask>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
    <userTask id="usertask2" name="部门经理审核"></userTask>
    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
    <userTask id="usertask3" name="人事复核"></userTask>
    <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>
    <endEvent id="endevent1" name="End"></endEvent>
    <sequenceFlow id="flow4" sourceRef="usertask3" targetRef="endevent1"></sequenceFlow>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_myProcess">
    <bpmndi:BPMNPlane bpmnElement="myProcess" id="BPMNPlane_myProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="BPMNShape_startevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="130.0" y="160.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="210.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
        <omgdc:Bounds height="55.0" width="105.0" x="360.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
        <omgdc:Bounds height="55.0" width="105.0" x="510.0" y="150.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="BPMNShape_endevent1">
        <omgdc:Bounds height="35.0" width="35.0" x="660.0" y="160.0"></omgdc:Bounds>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
        <omgdi:waypoint x="165.0" y="177.0"></omgdi:waypoint>
        <omgdi:waypoint x="210.0" y="177.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
        <omgdi:waypoint x="315.0" y="177.0"></omgdi:waypoint>
        <omgdi:waypoint x="360.0" y="177.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
        <omgdi:waypoint x="465.0" y="177.0"></omgdi:waypoint>
        <omgdi:waypoint x="510.0" y="177.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
        <omgdi:waypoint x="615.0" y="177.0"></omgdi:waypoint>
        <omgdi:waypoint x="660.0" y="177.0"></omgdi:waypoint>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

2.2 Steps to use

deploy activiti

Activiti is a workflow engine (in fact, it is a bunch of jar package APIs). The business system can access (operate) the interface of activiti to conveniently operate process-related data, so that the workflow environment can be integrated with the environment of the business system. .

process definition

Use the activiti process modeling tool (activity-designer) to define business processes (.bpmn files).

The .bpmn file is the business process definition file, which defines the business process through xml.

Process Definition Deployment

activiti deploys business process definitions (.bpmn files).

Use the api provided by activiti to store the process definition content, and you can query the defined content during the execution of Activiti

Activiti executes and stores the process definition content in the database

Start a process instance

Process instance is also called: ProcessInstance

Starting a process instance means starting the operation of a business process.

After the deployment of the employee leave process definition is completed, if Zhang San wants to ask for leave, he can start a process instance, and if Li Si wants to ask for leave, he can also start a process instance, and the execution of the two processes does not affect each other.

User query to-do tasks (Task)

Because the business process of the system has been handed over to activiti for management, through activiti, you can query where the current process is executed, and what tasks the current user needs to handle. These activiti help us manage these, without the need for developers to write queries in sql statements .

User handles tasks

After the user queries the pending tasks, he can handle a certain task. If the task is completed, other users need to handle it. For example, after the purchase order is created, it will be reviewed by the department manager. This process is also completed by activiti for us.

end of process

When the task is completed and there is no next task node, the process instance is completed.

Three, Activiti environment

3.1 Development environment

  • Jdk1.8 or above
  • Mysql 5 and above
  • Tomcat8.5
  • IDEA

Note: activiti's process definition tool plug-in can be installed under IDEA or Eclipse tool

3.2 Activiti environment

We use: Activiti7.0.0.Beta1spring5 is supported by default.

Recommend an open source and free Spring Boot most complete tutorial:

https://github.com/javastacks/spring-boot-best-practice

3.2.1 Download activiti7

Activiti download address: http://activiti.org/download.html, Maven's dependencies are as follows:

<dependencyManagement>
   <dependencies>
       <dependency>
           <groupId>org.activiti</groupId>
           <artifactId>activiti-dependencies</artifactId>
           <version>7.0.0.Beta1</version>
           <scope>import</scope>
           <type>pom</type>
       </dependency>
   </dependencies>
</dependencyManagement>
1) Database:

The operation of activiti requires the support of the database. The supported databases are: h2, mysql, oracle, postgres, mssql, db2.

3.2.2 Installation under the process designer IDEA

Find the submenu "Settings" in the File menu of IDEA, and then select the "plugins" menu on the left, as shown in the following figure:

At this point we can search for the actiBPM plug-in, which is Activiti Designerthe IDEA version, and we click Install to install it.

After installation, the page is as follows:

Prompt that idea needs to be restarted, click Restart.

After the restart is complete, open the Plugins (plugins list) under Settings again, click Installed (installed plugins) on the right, and if you see actiBPM in the list, it means that it has been installed successfully, as shown in the following figure:

In the following courses, we will use this process designer for Activiti process design.

3.3 Activiti's database support

Activiti needs the support of the database at runtime, and uses 25 tables to read the content of the process definition node into the database table for subsequent use.

3.3.1 Databases supported by Activiti

The databases and versions supported by activiti are as follows:

3.3.2 Generate tables in MySQL

3.3.2.1 Create database

Create mysql database activiti (any name):

CREATE DATABASE activiti DEFAULT CHARACTER SET utf8;

3.3.2.2 Using java code to generate tables

  • Create a java project

Use idea to create a java maven project, named: activiti01.

  • Add coordinates of maven dependencies (jar package)

First, you need to add the jar package required by ProcessEngine to the java project, including:

  1. activities-engine-7.0.0.beta1.jar
  2. The jar packages that activiti depends on: mybatis, alf4j, log4j, etc.
  3. The spring package that activiti depends on
  4. mysql database driver
  5. Third-party data connection pool dbcp
  6. unit-test-junit-4.12.jar

We use maven to build the project, so the coordinates corresponding to these jars should be imported into the pom.xml file.

The complete dependencies are as follows:

<properties>
    <slf4j.version>1.6.6</slf4j.version>
    <log4j.version>1.2.12</log4j.version>
    <activiti.version>7.0.0.Beta1</activiti.version>
</properties>
<dependencies>
    <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 模型处理 -->
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-bpmn-model</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <!-- bpmn 转换 -->
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-bpmn-converter</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <!-- bpmn json数据转换 -->
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-json-converter</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <!-- bpmn 布局 -->
    <dependency>
        <groupId>org.activiti</groupId>
        <artifactId>activiti-bpmn-layout</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <!-- activiti 云支持 -->
    <dependency>
        <groupId>org.activiti.cloud</groupId>
        <artifactId>activiti-cloud-services-api</artifactId>
        <version>${activiti.version}</version>
    </dependency>
    <!-- mysql驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.40</version>
    </dependency>
    <!-- mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.4.5</version>
    </dependency>
    <!-- 链接池 -->
    <dependency>
        <groupId>commons-dbcp</groupId>
        <artifactId>commons-dbcp</artifactId>
        <version>1.4</version>
    </dependency>
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</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>
</dependencies>
  • Add log4j log configuration

We use the log4j log package, which can configure the log

Create log4j.properties under resources

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=f:\act\activiti.log
log4j.appender.LOGFILE.Append=true
log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
  • Add activiti configuration file

We use the default method provided by activiti to create mysql tables.

The requirement of the default method is to create activiti.cfg.xmla file . Note: the directory and file name of the default method cannot be modified, because the source code of activiti has been set to read files with a fixed file name in a fixed directory.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
</beans>
  • Configure in activiti.cfg.xml

activiti.cfg.xmlThe default method should be the name of the bean in the middle processEngineConfiguration, and the name cannot be modified

There are 2 configuration methods here: one is to configure the data source separately, and the other is not to configure the data source separately

1. Direct configurationprocessEngineConfiguration

processEngineConfigurationIt is used to create ProcessEngine, and the operation of the database will be performed ProcessEnginewhen .

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
    <!-- 默认id对应的值 为processEngineConfiguration -->
    <!-- processEngine Activiti的流程引擎 -->
    <bean id="processEngineConfiguration"
          class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="jdbcDriver" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql:///activiti"/>
        <property name="jdbcUsername" value="root"/>
        <property name="jdbcPassword" value="123456"/>
        <!-- activiti数据库表处理策略 -->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>

2. After configuring the data source, processEngineConfigurationrefer to

First configure the data source

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 这里可以使用 链接池 dbcp-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql:///activiti" />
        <property name="username" value="root" />
        <property name="password" value="123456" />
        <property name="maxActive" value="3" />
        <property name="maxIdle" value="1" />
    </bean>

    <bean id="processEngineConfiguration"
          class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <!-- 引用数据源 上面已经设置好了-->
        <property name="dataSource" ref="dataSource" />
        <!-- activiti数据库表处理策略 -->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>
  • Java class writing program to generate table

Create a test class, call the tool class of activiti, and generate the database tables needed by acitivti.

Direct use of the tool class provided by activiti will read the files ProcessEnginesunder the classpath by default , read the database configuration in it, create , and automatically create tables when creating .activiti.cfg.xmlProcessEngineProcessEngine

code show as below:

package com.itheima.activiti01.test;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.junit.Test;

public class TestDemo {
    /**
     * 生成 activiti的数据库表
     */
    @Test
    public void testCreateDbTable() {
        //使用classpath下的activiti.cfg.xml中的配置创建processEngine
  ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
  System.out.println(processEngine);
    }
}

illustrate:

  • Run the above program segment to complete the creation of the activiti table, and implement different data table processing strategies by changing the value of the parameter activiti.cfg.xmlin .databaseSchemaUpdate
  • When the above method getDefaultProcessEnginemethod is executed, activiti.cfg.xmlfind a fixed name from it processEngineConfiguration.

During the execution of the test program, the idea console will output logs, indicating that the program is creating a data table, similar to the following, pay attention to the content of the red line:

After the execution is complete, we check the database and create 25 tables. The results are as follows:

At this point, we have completed the creation of the database and tables required for activiti to run.

3.4 Table Structure Introduction

3.4.1 Naming rules and functions of tables

Seeing the table just created, we found that Activiti's tables all ACT_start with .

The second part is a two-letter designation that indicates the purpose of the table. The purpose also corresponds to the API of the service.

  • ACT_RE: 'RE' means repository. Tables with this prefix contain process definitions and process static resources (images, rules, etc.).
  • ACT_RU: 'RU' means runtime. These runtime tables contain running data such as process instances, tasks, variables, asynchronous tasks, and so on. Activiti only saves these data during the execution of the process instance, and deletes these records at the end of the process. In this way, the runtime table can always be small and fast.
  • ACT_HI: 'HI' means history. These tables contain historical data such as historical process instances, variables, tasks, etc.
  • ACT_GE: GE means general. Common data, used in different scenarios
3.4.2 Activiti data table introduction

image-20230515095521896

Four, Activiti class relationship diagram

Above we have completed the generation of the Activiti database table. In the java code, we call the tool class of Activiti. Let's understand the class relationship of Activiti

4.1 Class Diagram

In the new version, we can find through experiments IdentityServicethat FormServiceboth Serivce have been deleted.

So we will not explain these two Services later, but there are still these two Services in the old version, students need to understand

4.2 activiti.cfg.xml

The engine configuration file of activiti includes: ProcessEngineConfigurationdefinition, data source definition, transaction manager, etc. This file is actually a spring configuration file.

4.3 Process engine configuration class

The configuration class of the process engine ( ProcessEngineConfiguration), through which ProcessEngineConfigurationthe workflow engine can be created ProceccEngine, the two commonly used methods are as follows:

4.3.1 StandaloneProcessEngineConfiguration

Use StandaloneProcessEngineConfigurationActivitican run alone, to create ProcessEngine, Activitiwill handle the transaction by itself.

Configuration file method:

Usually activiti.cfg.xmla bean with an id processEngineConfigurationof .

Methods as below:

<bean id="processEngineConfiguration"
          class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <!--配置数据库相关的信息-->
        <!--数据库驱动-->
        <property name="jdbcDriver" value="com.mysql.jdbc.Driver"/>
        <!--数据库链接-->
        <property name="jdbcUrl" value="jdbc:mysql:///activiti"/>
        <!--数据库用户名-->
        <property name="jdbcUsername" value="root"/>
        <!--数据库密码-->
        <property name="jdbcPassword" value="123456"/>
        <!--actviti数据库表在生成时的策略  true - 如果数据库中已经存在相应的表,那么直接使用,如果不存在,那么会创建-->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>

You can also join the connection pool:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                    http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///activiti"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
        <property name="maxActive" value="3"/>
        <property name="maxIdle" value="1"/>
    </bean>
    <!--在默认方式下 bean的id  固定为 processEngineConfiguration-->
    <bean id="processEngineConfiguration"
          class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <!--引入上面配置好的 链接池-->
        <property name="dataSource" ref="dataSource"/>
        <!--actviti数据库表在生成时的策略  true - 如果数据库中已经存在相应的表,那么直接使用,如果不存在,那么会创建-->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>
4.3.2 SpringProcessEngineConfiguration

Through org.activiti.spring.SpringProcessEngineConfigurationintegration with Spring.

Create an integrated configuration file for spring and activiti:

activity-spring.cfg.xml(name can be modified)

<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
   xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
      http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
      http://www.springframework.org/schema/mvc
      http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd
      http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.1.xsd
      http://www.springframework.org/schema/aop
      http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
      http://www.springframework.org/schema/tx
      http://www.springframework.org/schema/tx/spring-tx-3.1.xsd ">
   <!-- 工作流引擎配置bean -->
   <bean id="processEngineConfiguration" class="org.activiti.spring.SpringProcessEngineConfiguration">
      <!-- 数据源 -->
      <property name="dataSource" ref="dataSource" />
      <!-- 使用spring事务管理器 -->
      <property name="transactionManager" ref="transactionManager" />
      <!-- 数据库策略 -->
      <property name="databaseSchemaUpdate" value="drop-create" />
      <!-- activiti的定时任务关闭 -->
     <property name="jobExecutorActivate" value="false" />
   </bean>
   <!-- 流程引擎 -->
   <bean id="processEngine" class="org.activiti.spring.ProcessEngineFactoryBean">
      <property name="processEngineConfiguration" ref="processEngineConfiguration" />
   </bean>
   <!-- 资源服务service -->
   <bean id="repositoryService" factory-bean="processEngine"
      factory-method="getRepositoryService" />
   <!-- 流程运行service -->
   <bean id="runtimeService" factory-bean="processEngine"
      factory-method="getRuntimeService" />
   <!-- 任务管理service -->
   <bean id="taskService" factory-bean="processEngine"
      factory-method="getTaskService" />
   <!-- 历史管理service -->
   <bean id="historyService" factory-bean="processEngine" factory-method="getHistoryService" />
   <!-- 用户管理service -->
   <bean id="identityService" factory-bean="processEngine" factory-method="getIdentityService" />
   <!-- 引擎管理service -->
   <bean id="managementService" factory-bean="processEngine" factory-method="getManagementService" />
   <!-- 数据源 -->
   <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="mysql" />
      <property name="maxActive" value="3" />
      <property name="maxIdle" value="1" />
   </bean>
   <!-- 事务管理器 -->
   <bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource" />
   </bean>
   <!-- 通知 -->
   <tx:advice id="txAdvice" transaction-manager="transactionManager">
      <tx:attributes></tx:attributes>
          <!-- 传播行为 -->
          <tx:method name="save*" propagation="REQUIRED" />
          <tx:method name="insert*" propagation="REQUIRED" />
          <tx:method name="delete*" propagation="REQUIRED" />
          <tx:method name="update*" propagation="REQUIRED" />
          <tx:method name="find*" propagation="SUPPORTS" read-only="true" />
          <tx:method name="get*" propagation="SUPPORTS" read-only="true" />
       </tx:attributes>
   </tx:advice>
   <!-- 切面,根据具体项目修改切点配置 -->
   <aop:config proxy-target-class="true">
      <aop:advisor advice-ref="txAdvice"  pointcut="execution(* com.itheima.ihrm.service.impl.*.(..))"* />
  </aop:config>
</beans>

createprocessEngineConfiguration

ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml")

activiti.cfg.xmlThere must be a processEngineConfigurationbean in the code requirement above

You can also use the following method to change the name of the bean:

ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(String resource, String beanName);

4.4 Workflow engine creation

Workflow engine (ProcessEngine), which is equivalent to a facade interface, is ProcessEngineConfigurationcreated processEngineby ProcessEnginecreating each service interface.

4.4.1 Default creation method

The file name and path are fixed activiti.cfg.xml, and activiti.cfg.xmlthere processEngineConfigurationare , you can use the following code to create processEngine:

//直接使用工具类 ProcessEngines,使用classpath下的activiti.cfg.xml中的配置创建processEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
System.out.println(processEngine);
4.4.2 General creation method
//先构建ProcessEngineConfiguration
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
//通过ProcessEngineConfiguration创建ProcessEngine,此时会创建数据库
ProcessEngine processEngine = configuration.buildProcessEngine();
4.5 Servcie service interface

Service is the service interface provided by the workflow engine for workflow deployment, execution, and management. We use these interfaces to be the data tables corresponding to the operation services

4.5.1 Service creation method

Create Service through ProcessEngine

The way is as follows:

RuntimeService runtimeService = processEngine.getRuntimeService();
RepositoryService repositoryService = processEngine.getRepositoryService();
TaskService taskService = processEngine.getTaskService();

4.5.2 Overview of Services

a brief introdction:

  • RepositoryService

It is the resource management class of activiti, which provides operations for managing and controlling process release packages and process definitions. A business flowchart designed with a workflow modeling tool needs to use this service to deploy the contents of the process definition file to the computer.

In addition to deploying process definitions, you can also: Query the release package and process definition in the engine.

Pause or activate release packages, corresponding to all and specific process definitions. Suspending means they can no longer perform any operations, activating is the corresponding reverse operation. Access to various resources, such as files included in the distribution package, or flowcharts automatically generated by the engine.

Get the pojo version of the process definition, which can be used to parse the process through java instead of xml.

  • RuntimeService

Activiti's process operation management class. You can get a lot of information about process execution from this service class

  • TaskService

Activiti's task management class. Task information can be obtained from this class.

  • HistoryService

Activiti's history management class can query historical information. When the process is executed, the engine will save a lot of data (according to the configuration), such as the start time of the process instance, the participants of the task, the time to complete the task, the execution path of each process instance, etc. wait. This service mainly obtains these data through the query function.

  • ManagementService

Activiti's engine management class provides management and maintenance functions for the Activiti process engine. These functions are not used in workflow-driven applications and are mainly used for the daily maintenance of the Activiti system.

5. Getting Started with Activiti

In this chapter, let's create an Activiti workflow and start the process.

Creating an Activiti workflow mainly includes the following steps:

  • Define the process, according to the BPMN specification, use the process definition tool to describe the entire process with process symbols
  • Deploy the process, load the drawn process definition file into the database, and generate table data
  • Start the process and use java code to manipulate the contents of the database table

5.1 Process symbols

BPMN 2.0 is an acronym for Business Process Modeling Notation 2.0.

It was created and continuously developed by the Business Process Management Initiative, a not-for-profit association. As a sign, BPMN 2.0 is a set of notation specifications that use some notations to clarify the flow chart of business process design, which can improve the communication efficiency of business modeling.

Currently BPMN2.0 is the latest version, which is used for layout and visual communication in the context of BPM.

Next, let's first understand the common symbols in process design.

The basic compliance of BPMN2.0 mainly includes:

Event Event

Activity Activity

Activity is a general term for work or task. An activity can be a task or a sub-process of the current process; secondly, you can also specify different types for the activity. Common activities are as follows:

GatewayGateWay

Gateways are used to process decisions. There are several commonly used gateways that need to be understood:

exclusive gateway(x)

- Only one path will be chosen. When the process is executed to the gateway, it is calculated one by one according to the order of the output flow, and when the calculation result of the condition is true, continue to execute the output flow of the current gateway;

  • If multiple routes evaluate to true, the first true route is executed. If none of the gateways evaluate to true, the engine throws an exception.
  • The exclusive gateway needs to be used in combination with the conditional sequence flow. The default attribute specifies the default sequence flow. When all the conditions are not met, the default sequence flow will be executed.

Parallel Gateway(+)

- all paths will be selected at the same time

  • Split - Executes all output sequence flows in parallel, creating a parallel execution line for each sequence flow.
  • Merge——All lines that are split from the parallel gateway and executed are waiting here, until all lines are executed before continuing to execute downwards.

Inclusive Gateway(+)

-- Multiple lines can be executed at the same time, or conditions can be set on the gateway

  • Split - Evaluate the expression on each line, when the expression evaluates to true, create a parallel line and continue execution
  • Merge——All lines that are split from the parallel gateway and executed are waiting here, until all lines are executed before continuing to execute downwards.

Event Gateway(+)

—— Specially set for intermediate capture events, allowing multiple output streams to point to multiple different intermediate capture events. When the process is executed to the event gateway, the process is in a waiting state and needs to wait for an event to be thrown to convert the waiting state into an active state.

Flow to Flow

A flow is a wire connecting two process nodes. Common flow directions include the following:

5.2 Use of Process Designer

Activiti-Designer uses
Palette

It can be used after installing the plug-in in idea, and the drawing board includes the following nodes:

  • Connection—connection
  • Event—event
  • Task—task
  • Gateway—gateway
  • Container—container
  • Boundary event—Boundary event
  • Intermediate event- - Intermediate event

After the flow chart is designed, save and generate a .bpmn file

New process (IDEA tool)

First select the directory where the graphics are stored (select the bpmn directory under resources), click the menu: New -> BpmnFile, as shown in the figure:

A box as shown in the figure below pops up, enter evection to indicate the business trip approval process:

After naming the event (the default extension is bpmn), you can see the process design page, as shown in the figure:

The left area is the drawing area, and the right area is the palette area

Click the elements of the drawing board with the mouse to draw on the left side

drawing process

Use the skateboard to draw the process, by dragging the icon from the right to the left drawing board, the final effect is as follows:

Specify the process definition Key

The process definition key is the identification of the process definition, and the key of the process can be viewed through the properties view

designated task leader

Specify the person in charge of each task node in the properties view, for example: the person in charge of filling out the business trip application is zhangsan

  • The person in charge of manager approval is jerry
  • The person in charge of approval by the general manager is Jack
  • The person in charge of financial approval is Rose

6. Process operation

6.1 Process Definition

overview

The process definition is to describe the business process offline according to the bpmn2.0 standard, and usually use the plug-in in the idea to model the business process.

Use the designer designer under the idea to draw the process, and two files will be generated: .bpmn and .png

.bpmn file

Using activiti-desinger to design a business process will generate a .bpmn file, above which we have created the bpmn file

The BPMN 2.0 root node is the definitions node. In this element, multiple process definitions can be defined (but we recommend that each file contains only one process definition, which can simplify the maintenance difficulty during the development process).

Note that the definitions element must contain at least the declarations of xmlns and targetNamespace. targetNamespace can be any value, it is used to classify the process instance.

  • Process definition part: defines the description of each node of the process and the process flow between nodes.
  • Process layout definition: define information such as the position coordinates of each node of the process on the flow chart.
Generate .png image file

Operation mode in IDEA tool

1. Modify the file suffix to xml

First, rename the evection.bpmn file to evection.xml, as shown below:

The bpmn file before evection.xml is modified, the effect is as follows:

2. Use the designer to open the .xml file

On the evection.xml file, right-click and select the Diagrams menu, then selectShow BPMN2.0 Designer…

3. View open files

After opening, garbled characters appear, as shown in the figure:

4. Solve Chinese garbled characters

1. Open Settings, find File Encodings, and select UTF-8 for all encoding options

2. Open the IDEA installation path and find the following installation directory

It depends on the version I have installed. I am using a 64-bit idea, so idea64.exe.vmoptionsadd a command to the last line of the file:-Dfile.encoding=UTF-8

As follows:

Be careful not to have spaces, otherwise IDEA will not open when you restart it, and then restart IDEA.

If the above method has been completed and garbled characters still appear, modify another file and add: at the end of the file -Dfile.encoding=UTF-8, and then restart idea, as shown in the figure:

Finally, on the evection.xml file, right-click and select the Diagrams menu, and then select to Show BPMN2.0 Designer…see the generated picture, as shown in the figure:

So far, solve the garbled problem

5. Export as an image file

Click Export To Filethe small icon to open the following window, pay attention to fill in the file name and extension, and choose the location to save the picture:

Then, we copy the png file to the bpmn directory under resources, and rename evection.xml to evection.bpmn.

6.2 Process Definition Deployment

overview

Deploying the process defined above in the designer to the activiti database is the process definition deployment.

Add and deploy the bpmn and png files of the process definition to activiti one by one by calling the api of activiti, or pack the two files into a zip package for deployment.

single file deployment

Deploy the bpmn file and png image file respectively.

public class ActivitiDemo {
    /**
     * 部署流程定义
     */
    @Test
    public void testDeployment(){
//        1、创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        2、得到RepositoryService实例
        RepositoryService repositoryService = processEngine.getRepositoryService();
//        3、使用RepositoryService进行部署
        Deployment deployment = repositoryService.createDeployment()
                .addClasspathResource("bpmn/evection.bpmn") // 添加bpmn资源
                .addClasspathResource("bpmn/evection.png")  // 添加png资源
                .name("出差申请流程")
                .deploy();
//        4、输出部署信息
        System.out.println("流程部署id:" + deployment.getId());
        System.out.println("流程部署名称:" + deployment.getName());
    }
}

After performing this operation, activiti will save the bpm file and image file specified in the above code in the activiti database.

Compressed package deployment method

Compress evection.bpmnand evection.pngcompress into a zip package.

@Test
 public void deployProcessByZip() {
  // 定义zip输入流
  InputStream inputStream = this
    .getClass()
    .getClassLoader()
    .getResourceAsStream(
      "bpmn/evection.zip");
  ZipInputStream zipInputStream = new ZipInputStream(inputStream);
  // 获取repositoryService
  RepositoryService repositoryService = processEngine
    .getRepositoryService();
  // 流程部署
  Deployment deployment = repositoryService.createDeployment()
    .addZipInputStream(zipInputStream)
    .deploy();
  System.out.println("流程部署id:" + deployment.getId());
  System.out.println("流程部署名称:" + deployment.getName());
 }

After performing this operation, activiti will save the bpm file and image file specified in the above code in the activiti database.

Operational Data Sheet

The three tables for operating activiti after the process definition is deployed are as follows:

  • act_re_deploymentProcess definition deployment table, each deployment adds a record
  • act_re_procdefProcess definition table, deploying each new process definition will add a record to this table
  • act_ge_bytearrayProcess resource table

Next, let's take a look at what data is written:

SELECT * FROM act_re_deployment #流程定义部署表,记录流程部署信息

result:

SELECT * FROM act_re_procdef #流程定义表,记录流程定义信息

result:

Note that the KEY field is a keyword used to uniquely identify different processes

SELECT * FROM act_ge_bytearray #资源表

result:

Notice:

act_re_deploymentAnd act_re_procdefone-to-many relationship, a deployment generates a record in the process deployment table, but a deployment can deploy multiple process definitions, and each process definition generates a record in the process definition table. Each process definition act_ge_bytearraywill have two resource records, bpmn and png.

Suggestion: Deploy one process at a time, so that the deployment table and process definition table have a one-to-one relationship, which is convenient for reading process deployment and process definition information.

6.3 Start process instance

After the process definition is deployed in activiti, the business process can be managed through the workflow, that is to say, the business trip application process deployed above can be used.

For this process, starting a process means launching a new business trip application form, which is equivalent to the relationship between a java class and a java object. After the class is defined, you need to create an object with new. Of course, you can new multiple objects. For the business trip application process, Zhang San needs to start a process instance when he initiates a business trip application form, and a process instance needs to be started when the business trip application form initiates a business trip order.

code show as below:

    /**
     * 启动流程实例
     */
    @Test
    public void testStartProcess(){
//        1、创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        2、获取RunTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
//        3、根据流程定义Id启动流程
        ProcessInstance processInstance = runtimeService
                .startProcessInstanceByKey("myEvection");
//        输出内容
        System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
        System.out.println("流程实例id:" + processInstance.getId());
        System.out.println("当前活动Id:" + processInstance.getActivityId());
    }

The output is as follows:

Operational Data Sheet

  • act_hi_actinstProcess instance execution history
  • act_hi_identitylinkProcess participation user history information
  • act_hi_procinstProcess Instance History Information
  • act_hi_taskinstProcess task history information
  • act_ru_executionProcess Execution Information
  • act_ru_identitylinkParticipating user information of the process
  • act_ru_tasktask information

6.4 Task query

After the process is started, the person in charge of the task can query the tasks that he needs to process currently, and the tasks that are queried are all to-do tasks of the user.

/**
     * 查询当前个人待执行的任务
      */
    @Test
    public void testFindPersonalTaskList() {
//        任务负责人
        String assignee = "zhangsan";
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        创建TaskService
        TaskService taskService = processEngine.getTaskService();
//        根据流程key 和 任务负责人 查询任务
        List<Task> list = taskService.createTaskQuery()
                .processDefinitionKey("myEvection") //流程Key
                .taskAssignee(assignee)//只查询该任务负责人的任务
                .list();

        for (Task task : list) {

            System.out.println("流程实例id:" + task.getProcessInstanceId());
            System.out.println("任务id:" + task.getId());
            System.out.println("任务负责人:" + task.getAssignee());
            System.out.println("任务名称:" + task.getName());

        }
    }

The output is as follows:

流程实例id:2501
任务id:2505
任务负责人:zhangsan
任务名称:创建出差申请

6.5 Process task processing

The task leader queries the to-do tasks, selects the tasks to process, and completes the tasks.

// 完成任务
    @Test
    public void completTask(){
//        获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        获取taskService
        TaskService taskService = processEngine.getTaskService();

//        根据流程key 和 任务的负责人 查询任务
//        返回一个任务对象
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myEvection") //流程Key
                .taskAssignee("zhangsan")  //要查询的负责人
                .singleResult();

//        完成任务,参数:任务id
        taskService.complete(task.getId());
    }

6.6 Process definition information query

Query process-related information, including process definition, process deployment, and process definition version

    /**
     * 查询流程定义
     */
    @Test
    public void queryProcessDefinition(){
        //        获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        repositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
//        得到ProcessDefinitionQuery 对象
        ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//          查询出当前所有的流程定义
//          条件:processDefinitionKey =evection
//          orderByProcessDefinitionVersion 按照版本排序
//        desc倒叙
//        list 返回集合
        List<ProcessDefinition> definitionList = processDefinitionQuery.processDefinitionKey("myEvection")
                .orderByProcessDefinitionVersion()
                .desc()
                .list();
//      输出流程定义信息
        for (ProcessDefinition processDefinition : definitionList) {
            System.out.println("流程定义 id="+processDefinition.getId());
            System.out.println("流程定义 name="+processDefinition.getName());
            System.out.println("流程定义 key="+processDefinition.getKey());
            System.out.println("流程定义 Version="+processDefinition.getVersion());
            System.out.println("流程部署ID ="+processDefinition.getDeploymentId());
        }

    }

Output result:

流程定义id:myEvection:1:4
流程定义名称:出差申请单
流程定义key:myEvection
流程定义版本:1

6.7 Process deletion

public void deleteDeployment() {
  // 流程部署id
  String deploymentId = "1";

    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    // 通过流程引擎获取repositoryService
  RepositoryService repositoryService = processEngine
    .getRepositoryService();
  //删除流程定义,如果该流程定义已有流程实例启动则删除时出错
  repositoryService.deleteDeployment(deploymentId);
  //设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式,如果流程
  //repositoryService.deleteDeployment(deploymentId, true);
 }

illustrate:

  • Use the repositoryService to delete the process definition, and the history table information will not be deleted
  • If there is no running process under the process definition, it can be deleted with normal.

If there is an already running process under the process definition, use common delete to report an error, and use the cascade delete method to delete all the process and related records.

Delete the unfinished process nodes first, and finally delete the process definition information completely

Cascading delete operations in project development are generally only available to super administrators.

6.8 Process resource download

Now our process resource files have been uploaded to the database. If other users want to view these resource files, they can download the resource files from the database to the local.

The solutions are:

  • Jdbc reads blob type and clob type data and saves them to the file directory
  • Use activiti's api to achieve

Use commons-io.jar to solve IO operations

Introduce commons-io dependency package

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

Obtain process definition resources through process definition objects, obtain bpmn and png

import org.apache.commons.io.IOUtils;

@Test
    public void deleteDeployment(){
//        获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        获取repositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
//        根据部署id 删除部署信息,如果想要级联删除,可以添加第二个参数,true
        repositoryService.deleteDeployment("1");
    }

    public void  queryBpmnFile() throws IOException {
//        1、得到引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        2、获取repositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();
//        3、得到查询器:ProcessDefinitionQuery,设置查询条件,得到想要的流程定义
        ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey("myEvection")
                .singleResult();
//        4、通过流程定义信息,得到部署ID
        String deploymentId = processDefinition.getDeploymentId();
//        5、通过repositoryService的方法,实现读取图片信息和bpmn信息
//        png图片的流
        InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
//        bpmn文件的流
        InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
//        6、构造OutputStream流
        File file_png = new File("d:/evectionflow01.png");
        File file_bpmn = new File("d:/evectionflow01.bpmn");
        FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);
        FileOutputStream pngOut = new FileOutputStream(file_png);
//        7、输入流,输出流的转换
        IOUtils.copy(pngInput,pngOut);
        IOUtils.copy(bpmnInput,bpmnOut);
//        8、关闭流
        pngOut.close();
        bpmnOut.close();
        pngInput.close();
        bpmnInput.close();
    }

illustrate:

  • deploymentIdDeploy the ID for the process
  • resource_nameis act_ge_bytearraythe value of the NAME_ column in the table
  • repositoryServiceThe method used getDeploymentResourceNamescan get the names of all files under the specified deployment
  • The method used repositoryServiceto getResourceAsStreampass in the deployment ID and resource image name can get the input stream of the file with the specified name under the deployment

The last one outputs the image resources in the input stream.

6.9 View process history information

act_hi_*Even if the process definition has been deleted, the historical information of process execution is still stored in the relevant tables of activiti through the previous analysis . So we can still query the historical information of the process execution, and we can HistoryServiceview the relevant historical records through .

    /**
     * 查看历史信息
     */
    @Test
    public void findHistoryInfo(){
//      获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//        获取HistoryService
        HistoryService historyService = processEngine.getHistoryService();
//        获取 actinst表的查询对象
        HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
//        查询 actinst表,条件:根据 InstanceId 查询
//        instanceQuery.processInstanceId("2501");
//        查询 actinst表,条件:根据 DefinitionId 查询
        instanceQuery.processDefinitionId("myEvection:1:4");
//        增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序
        instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
//        查询所有内容
        List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
//        输出
        for (HistoricActivityInstance hi : activityInstanceList) {
            System.out.println(hi.getActivityId());
            System.out.println(hi.getActivityName());
            System.out.println(hi.getProcessDefinitionId());
            System.out.println(hi.getProcessInstanceId());
            System.out.println("<==========================>");
        }
    }

Summarize

The basic functions are introduced and completed. If you need more advanced functions such as suspending, activating process instances, process variables, etc., please refer to

https://andyoung.blog.csdn.net/article/details/118345330

The combination of workflow engine Activiti and Spring boot will make development easier, let’s take a look

https://andyoung.blog.csdn.net/article/details/118372175

Source: https://blog.csdn.net/agonie201218/article/details/118198535

Recent hot article recommendation:

1. 1,000+ Java interview questions and answers (2022 latest version)

2. Brilliant! Java coroutines are coming. . .

3. Spring Boot 2.x tutorial, too comprehensive!

4. Don't fill the screen with explosions and explosions, try the decorator mode, this is the elegant way! !

5. The latest release of "Java Development Manual (Songshan Edition)", download quickly!

Feel good, don't forget to like + forward!

Guess you like

Origin blog.csdn.net/youanyyou/article/details/130705348