[activiti 7] spring boot integrates activiti 7 workflow

Preface

1. What is workflow:

Workflow ( Workflow) is the automated execution and management of business processes through computers. It mainly solves the problem of "automating the process of transferring documents, information or tasks between multiple participants according to certain predefined rules, so as to achieve an expected business goal, or to promote the realization of this goal."

2. Workflow system:

If 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 only assists in business process management. Even if there is no workflow business system, it can be developed and run. However, with workflow, business processes can be better managed and the scalability of the system can be improved.

3. Implementation method:

Before there was a dedicated workflow engine, in order to achieve process control, our usual approach was to use the value of the status field to track changes in the process. In this way, users without roles can decide whether to display records through the value of the status field.
For records that can be viewed with permission, the current user decides whether to approve the qualified operation based on his or her role. If qualified, set a value in the status field to represent qualified; of course, if not qualified, you also need to set a value to represent unqualified.
This is the most primitive way. Although 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 after the business process changes, our program does not need to be changed. If such an effect can be achieved, then the adaptability of our business system will be greatly improved.


1. Overview of Activiti 7

1.1 Introduction to activiti

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 complex business processes from the business system and define them using the specialized modeling language BPMN2.0. The business processes are executed according to the pre-defined processes, and the system processes are implemented by Activiti. Management, reducing the workload of system upgrades and transformations due to process changes in business systems, thereby improving the robustness of the system and reducing system development and maintenance costs.

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

1.2 BPM and BPMN

BPM (Business Process Management) is a standardized construction of end-to-end business processes to continuously improve organizational business efficiency. Common business management education such as EMBA, MBA, etc. include BPM.

BPMN (Business Process Model AndNotation) - Business process model and notation is a set of standard business process modeling symbols developed by BPMI (BusinessProcess Management Initiative). Business processes can be created using the symbols provided by BPMN.
The BPMN1.0 specification was released in May 2004. BPMI was merged into the OMG (The Object Management Group) organization in September 2005. OMG released the final version of BPMN2.0 in January 2011.
Insert image description here
The specific development history is as follows:

BPMN is a BPM standard currently 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:

EventEvent

Events are represented by a circle and are things that happen while a process is running. The occurrence of events will affect the flow of the process. Events include three types: Start\Intermediate\End. As shown below:
Insert image description here

ActivitiesActivities

Activities are represented by rounded rectangles. One activity consists of multiple activities. The types of activities are divided into Task and Sub-Process. As shown below:
Insert image description here

Gateways Gateways

The gateway is represented by a diamond shape and is used to control branching and aggregation of the process. The specific symbols are as follows:
Insert image description here

Data data

  • Data Objects Data Objects
  • Data Inputs Data Inputs
  • Data OutPuts Data Outputs
  • Data Stores Data Stores
    Insert image description here

Connecting Objects Connecting Objects

  • Sequence Flows Sequence Flows: Sequence Flows are represented by solid arrows and represent the execution order of activities that will be executed in the process.
  • Message Flows Message Flows: Message Flows are represented by dotted hollow arrows, the flow of messages directly sent or received by two separate process participants.
  • Associations
  • Associations are represented by dotted lines and are used to show the input and output of activities.
  • Data Associations Data association relationships

Swimlanes

  • Pools pool
  • Lanes Road

Artifacts

1.Group group

2.Text Annotation text annotation

BPMN2-Diagram Types diagram types

1.Private Processes private processes

2.Public Processes

3. Choreographies Processes

related resources

  1. BPMN2.0 specification: http://www.omg.org/spec/BPMN/2.0/
  2. BPMN2 Editor: http://sourceforge.net/projects/bpmn/files/BPMN%20Editor/
  3. BPMN community: http://www.bpmn123.net

Bpmn graphics actually represent business processes through xml. The above .bpmn file 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. Usage steps

Integrating Activiti
Activiti is a workflow engine (actually a bunch of jar package APIs). When the business system accesses (operates) Activiti's interface, it can conveniently operate process-related data, so that the workflow environment can be integrated with the business system environment. together.

Process definition
Use the activiti process modeling tool (activity-designer) to define the business process (.bpmn file).
The .bpmn file is a business process definition file, which defines business processes through xml.

Process definition deployment
activiti deploys business process definitions (.bpmn files).
Use the API provided by Activiti to store the process definition content. During the execution of Activiti, you can query the defined content.
Activiti executes and stores the process definition content in the database (multiple process definitions can be deployed in one deployment).

Start a process instance.
A process instance is also called: ProcessInstance.
Starting a process instance means starting a business process.
After the employee leave process definition and deployment 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. 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 do. Activiti helps us manage these tasks without the need for Developers write their own queries in sql statements.

Users handle tasks.
After users query to-do tasks, they 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. (When the user's task is processed, the corresponding task node will be deleted)

End of process:
When the task processing is completed and there is no next task node, the process instance is completed. (The process instance will be deleted at this time)

Three, spring boot integrates activiti

3.1 Introducing dependencies

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

 <!-- 引入Activiti7 -->
 <dependency>
     <groupId>org.activiti</groupId>
     <artifactId>activiti-spring-boot-starter</artifactId>
     <version>7.1.0.M2</version>
     <exclusions>
         <exclusion>
             <groupId>org.mybatis</groupId>
             <artifactId>mybatis</artifactId>
         </exclusion>
         <exclusion>
             <artifactId>spring-security-config</artifactId>
             <groupId>org.springframework.security</groupId>
         </exclusion>
         <exclusion>
             <artifactId>spring-security-crypto</artifactId>
             <groupId>org.springframework.security</groupId>
         </exclusion>
         <exclusion>
             <artifactId>spring-security-web</artifactId>
             <groupId>org.springframework.security</groupId>
         </exclusion>
         <exclusion>
             <artifactId>spring-security-core</artifactId>
             <groupId>org.springframework.security</groupId>
         </exclusion>
         <exclusion>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
         </exclusion>
         <exclusion>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-web</artifactId>
         </exclusion>
     </exclusions>
 </dependency>
 <dependency>
     <groupId>org.activiti.dependencies</groupId>
     <artifactId>activiti-dependencies</artifactId>
     <version>7.1.0.M2</version>
     <type>pom</type>
 </dependency>
 <!-- 生成流程图 -->
 <dependency>
     <groupId>org.activiti</groupId>
     <artifactId>activiti-image-generator</artifactId>
     <version>7.1.0.M2</version>
 </dependency>

Database:
activiti requires the support of a database to run. The supported databases are: h2, mysql, oracle, postgres, mssql, db2.

3.2 Configure yml file

server:
  port: 8000
spring:
  datasource:
    url: jdbc:mysql://aliyuncs.com:3306/activiti
    username: *****
    password: *****
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.zaxxer.hikari.HikariDataSource
    hikari:
      minimum-idle: 0
      maximum-pool-size: 20
      idle-timeout: 10000
      auto-commit: true
      connection-test-query: SELECT 1
  # activiti7配置
  activiti:
    # 自动部署验证设置:true-开启(默认)、false-关闭
    check-process-definitions: false
    # 保存历史数据
    history-level: full
    # 检测历史表是否存在
    db-history-used: true
    # 关闭自动部署
    deployment-mode: never-fail
    # 对数据库中所有表进行更新操作,如果表不存在,则自动创建
    # create_drop:启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
    # drop-create:启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
    database-schema-update: true
    # 解决频繁查询SQL问题
    async-executor-activate: false
    #启用异步执行器
    job-executor-activate: false

3.3 Install ide plug-in process designer (BPMN-Activiti-Diagram)

Install plugin in ide

File -> settings -> plugins -> `BPMN-Activiti-Diagram`

After installation, you can design the process.

Create processa , newa BPMN 2.0 file.
Insert image description here
Select the newly created BPMN file, right-click to find the following selection, and then start drawing the flow chart (when drawing the flow chart, the corresponding xml attributes will be generated in the BPMN file)
Insert image description here
Insert image description here
here Let’s talk about the meaning of some corresponding attributes below the flow chart:

  • name: the name of the process node or the name of the process definition
  • key: The process definition key is the identifier of the process definition. View the key of the process through the properties view.
  • Assignee: Specify the person in charge of each task node in the properties view

After drawing, you can right-click and choose to export the process picture:
Insert image description here

3.4 Generate table

Start the project and automatically generate 25 tables in the corresponding database
Insert image description here

Note: The table generated in activiti version 7.1.M will lose some fields. We need to add them ourselves.
Run a sql to complete the missing table fields.

-- ----------------------------
-- 修复Activiti7的M4版本缺失字段Bug
-- ----------------------------
alter table ACT_RE_DEPLOYMENT add column PROJECT_RELEASE_VERSION_ varchar(255) DEFAULT NULL;
alter table ACT_RE_DEPLOYMENT add column VERSION_ varchar(255) DEFAULT NULL;

3.5 Introduction to table structure

Table naming rules and
tables used in Activiti all start with ACT_.

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. This prefixed table contains the process definition 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, etc. Activiti only saves this data during the execution of the process instance, and deletes these records when the process ends. In this way, the runtime table can be kept 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. General data, used in different scenarios

Activiti data table introduction

Table classification Table Name explain
General data
[ACT_GE_BYTEARRAY] Common process definitions and process resources
[ACT_GE_PROPERTY] System related properties
Process history
[ACT_HI_ACTINST] Historical process examples
[ACT_HI_ATTACHMENT] Historical process attachments
[ACT_HI_COMMENT] historical descriptive information
[ACT_HI_DETAIL] Detailed information about historical process operations
[ACT_HI_IDENTITYLINK] User relationships during historical process running
[ACT_HI_PROCINST] Historical process examples
[ACT_HI_TASKINST] Historical task examples
[ACT_HI_VARINST] Variable information in historical process operations
process definition table
[ACT_RE_DEPLOYMENT] Deployment unit information
[ACT_RE_MODEL] Model information
[ACT_RE_PROCDEF] Deployed process definition
Running instance table
[ACT_RU_EVENT_SUBSCR] runtime events
[ACT_RU_EXECUTION] Runtime process execution instance
[ACT_RU_IDENTITYLINK] Runtime user relationship information, which stores information related to task nodes and participants
[ACT_RU_JOB] runtime job
[ACT_RU_TASK] runtime tasks
[ACT_RU_VARIABLE] runtime variable table

3.6 Workflow engine and services

The workflow engine (ProcessEngine) is equivalent to a facade interface. ProcessEngine is created through ProcessEngineConfiguration, and each service interface is created through ProcessEngine.

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

But there is no need to create it in springBoot, you can just use it directly.

The following introduces the service interfaces needed

service name service function
RepositoryService activiti’s resource management class
RuntimeService activiti's process operation management class
TaskService activiti’s task management class
HistoryService activiti’s history management class
ManagerService activiti’s engine management class

RepositoryService
is activiti's resource management class, which provides operations for managing and controlling process release packages and process definitions. Business process diagrams designed using workflow modeling tools need to use this service to deploy the contents of the process definition file to the computer.

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

Pause or activate release packages for all and specific process definitions. Pause means they can no longer perform any operations, and activation is the opposite. Get a variety of resources, such as files included in the release 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 running management class. A lot of information about process execution can be obtained from this service class

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

The history management class of HistoryService
Activiti can query historical information. When executing a process, the engine will save a lot of data (according to configuration), such as process instance startup time, task participants, task completion time, and execution path of each process instance. etc. This service mainly obtains this data through query functions.

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 daily maintenance of the Activiti system.


4. Use of activiti

4.1 Process definition query and deployment

 /**
     * 查询流程定义列表
     * */
    @Override
    public Page<ProcessInstanceDto> ProcessDefinition(ActivitiParam param) {
    
    
        Page<ProcessInstanceDto> page = new Page(param.getCurrent(), param.getPageSize());
        Page<ProcessInstanceDto> pg = processDefinitionMapper.ProcessDefinition(page,param);
        if(!pg.getRecords().isEmpty()){
    
    
            pg.getRecords().forEach(processInstance ->{
    
    
                Deployment deployment = repositoryService.createDeploymentQuery()
                        .deploymentId(processInstance.getDeploymentId()).singleResult();
                processInstance.setDeploymentTime(deployment.getDeploymentTime());
            });
        }
        return pg;
    }

Here I did not use the query that comes with activiti, but wrote a query list interface by myself.

 /**
     * 手动流程部署
     * springboot启动就会自动部署流程
     * 部署时操作的表:act_ge_property(update)
     * act_re_procdef  ,act_re_deployment  ,act_ge_bytearray(insert)
     */
    @Override
    public void initDeployment(MultipartFile file) throws IOException {
    
    
        if(!file.isEmpty()){
    
    
            String fileName = StringUtils.cleanPath(file.getOriginalFilename());
            // 得到输入流(字节流)对象
            InputStream inputStream = file.getInputStream();
            // 文件的扩展名
            String extension = FilenameUtils.getExtension(fileName);
            // zip或者bar类型的文件用ZipInputStream方式部署
            if (extension.equals("zip") || extension.equals("bar")) {
    
    
                ZipInputStream zip = new ZipInputStream(inputStream);
                repositoryService.createDeployment()
                        .addClasspathResource(fileName)
                        .addZipInputStream(zip).deploy();
            } else if (extension.equals("xml")){
    
    
                // xml类型的文件
                repositoryService.createDeployment().addInputStream(fileName,inputStream).deploy();
            }
            return;
        }
        throw new RuntimeException("空文件");
    }
 /**
     * 挂起/激活流程
     */
    @Override
    public void suspendActiveProcessDefinition(ActivitiParam param) {
    
    
        String definitionId = param.getProcessDefinitionId();
        if(param.getSuspensionState()==2){
    
    
//          如果是挂起,可以执行激活的操作,参数1:流程定义id 参数2:是否级联挂起该流程定义下的流程实例,参数3:激活时间
            repositoryService.activateProcessDefinitionById(definitionId,
                    true,
                    new Date());
            System.out.println("流程定义id:"+definitionId+",已激活");
        }else {
    
    
//          如果是激活状态,改为挂起状态,参数1:流程定义id 参数2:是否级联挂起该流程定义下的流程实例 参数3 :暂停的时间
            repositoryService.suspendProcessDefinitionById(definitionId,
                    true,
                    new Date());
            System.out.println("流程定义id:"+definitionId+",已挂起");
        }

    }

The bpmn file under process will be automatically deployed when the project starts.

4.2 Start process instances and process tasks

The startup process instance actually means that someone initiates an application.

 /**
     * 初始化流程实例
     * 启动流程实例
     * 部署时操作的表:act_ge_property(update)
     * insert:act_hi_taskinst act_hi_actinst act_hi_procinst act_hi_identitylink
     * act_ru_execution、act_ru_identitylink、act_ru_task
     */
    @Override
    public void initProcessInstance(ActivitiParam param) {
    
    
        // 流程定义KEY(流程图的id,因为在表里存的是key)
        String processDefinitionKey = param.getKey();
        // 业务表KEY(用于把业务数据与Activiti7流程数据相关联)
        String businessKey = "4208169753200945";
        // 业务参数
        Map<String, Object> variables = new HashMap<>(16);
        variables.put("name","***");
        variables.put("time","一天");
        variables.put("description","相亲");
        org.activiti.engine.runtime.ProcessInstance processInstance = this.runtimeService
                .startProcessInstanceByKey(processDefinitionKey, businessKey, variables);
        System.out.println("流程实例ID:" + processInstance.getProcessInstanceId());
    }
 /**
     * 查询我的代办任务
     */
    @RequestMapping("/listTasksByAssignee")
    @ResponseBody
    public List<Task> listTasksByAssignee() {
    
    
        List<Task> tasks = taskService.listTasksByAssignee();
        return tasks;
    }
 /**
     * 完成任务
     */
    @RequestMapping("/completeTask")
    @ResponseBody
    public void completeTask() {
    
    
        taskService.completeTask();
    }

4.3 Editor corresponding interface

The process file is stored in the database as binary xml. After taking it out, you only need to convert it into a string. The same is true for saving.

 /**
     * 获取模型xml数据
     * */
    @Override
    public String getModelResource(String modelId) throws Exception {
    
    

        Model model = repositoryService.getModel(modelId);
        if (model == null) {
    
    
            throw new Exception("未找到该模型!");
        }
        try {
    
    
            byte[] modelBytes = repositoryService.getModelEditorSource(model.getId());
            String xmlString = new String(modelBytes, StandardCharsets.UTF_8);
            return xmlString;
        } catch (Exception e) {
    
    
            LOGGER.error("检索流程模型XML时出错", e);
            return "检索流程模型XML时出错";
        }
    }

Guess you like

Origin blog.csdn.net/m0_71621983/article/details/131832538