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:
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.Beta1
spring5 is supported by default.
Recommend an open source and free Spring Boot most complete tutorial:
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 Designer
the 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:
- activities-engine-7.0.0.beta1.jar
- The jar packages that activiti depends on: mybatis, alf4j, log4j, etc.
- The spring package that activiti depends on
- mysql database driver
- Third-party data connection pool dbcp
- 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.xml
a 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.xml
The 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
processEngineConfiguration
It is used to create ProcessEngine
, and the operation of the database will be performed ProcessEngine
when .
<?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, processEngineConfiguration
refer 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 ProcessEngines
under the classpath by default , read the database configuration in it, create , and automatically create tables when creating .activiti.cfg.xml
ProcessEngine
ProcessEngine
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.xml
in .databaseSchemaUpdate
- When the above method
getDefaultProcessEngine
method is executed,activiti.cfg.xml
find a fixed name from itprocessEngineConfiguration
.
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
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 IdentityService
that FormService
both 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: ProcessEngineConfiguration
definition, 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 ProcessEngineConfiguration
the workflow engine can be created ProceccEngine
, the two commonly used methods are as follows:
4.3.1 StandaloneProcessEngineConfiguration
Use StandaloneProcessEngineConfigurationActiviti
can run alone, to create ProcessEngine
, Activiti
will handle the transaction by itself.
Configuration file method:
Usually activiti.cfg.xml
a bean with an id processEngineConfiguration
of .
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.SpringProcessEngineConfiguration
integration 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.xml
There must be a processEngineConfiguration
bean 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 ProcessEngineConfiguration
created processEngine
by ProcessEngine
creating each service interface.
4.4.1 Default creation method
The file name and path are fixed activiti.cfg.xml
, and activiti.cfg.xml
there processEngineConfiguration
are , 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.vmoptions
add 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 File
the 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.bpmn
and evection.png
compress 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_deployment
Process definition deployment table, each deployment adds a recordact_re_procdef
Process definition table, deploying each new process definition will add a record to this tableact_ge_bytearray
Process 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_deployment
And act_re_procdef
one-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_bytearray
will 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_actinst
Process instance execution historyact_hi_identitylink
Process participation user history informationact_hi_procinst
Process Instance History Informationact_hi_taskinst
Process task history informationact_ru_execution
Process Execution Informationact_ru_identitylink
Participating user information of the processact_ru_task
task 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:
deploymentId
Deploy the ID for the processresource_name
isact_ge_bytearray
the value of the NAME_ column in the tablerepositoryService
The method usedgetDeploymentResourceNames
can get the names of all files under the specified deployment- The method used
repositoryService
togetResourceAsStream
pass 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 HistoryService
view 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
The combination of workflow engine Activiti and Spring boot will make development easier, let’s take a look
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!
5. The latest release of "Java Development Manual (Songshan Edition)", download quickly!
Feel good, don't forget to like + forward!