前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Spring Boot 集成 Activiti 工作流引擎 极简教程

Spring Boot 集成 Activiti 工作流引擎 极简教程

作者头像
一个会写诗的程序员
发布2021-06-17 19:06:58
5.2K0
发布2021-06-17 19:06:58
举报

Activiti 简介

Java 通用型工作流引擎:Activiti。

源代码:https://github.com/Activiti/Activiti

Activiti is the leading lightweight, java-centric open-source BPMN engine supporting real-world process automation needs.

Activiti 项目是一项新的基于Apache许可的开源BPM平台,从基础开始构建,旨在提供支持新的BPMN 2.0标准。

Activiti 是一种轻量级,可嵌入的BPM引擎,而且还设计适用于可扩展的云架构。 Activiti将提供宽松的 Apache 许可2.0,同时促进Activiti BPM引擎和BPMN 2.0的匹配。

Activiti 的核心服务组件

1.RepositoryService:提供一系列管理流程部署和流程定义的API。 2.RuntimeService:在流程运行时对流程实例进行管理与控制。 3.TaskService:对流程任务进行管理,例如任务提醒、任务完成和创建任务等。 4.IdentityService:提供对流程角色数据进行管理的API,这些角色数据包括用户组、用户及它们之间的关系。 5.ManagementService:提供对流程引擎进行管理和维护的服务。 6.HistoryService:对流程的历史数据进行操作,包括查询、删除这些历史数据。 7.FormService:表单服务。

Activiti应用场景:

多人协作的(或者需要动态变动)的业务流程场景。

业务流程模型 BPMN xml 配置文件

一个xml文件,activiti去解析这个文件,了解我们到底想干什么事。

test01.bpmn20.xml 实例:

<?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/processdef">

    <process id="test01" name="test01" isExecutable="true">
        <startEvent id="sid-d0c54d06-2073-4018-8381-e5e43f1b5578" name="Start"/>

        <serviceTask id="sid-0396a986-7e6b-4634-883b-1ee7db9aeb45"
                     activiti:exclusive="true"
                     name="Step1"
                     activiti:class="com.example.actividemo.ServiceTask1">
            <extensionElements>
                <activiti:field name="text1">
                    <activiti:string><![CDATA[test1]]></activiti:string>
                </activiti:field>
            </extensionElements>
        </serviceTask>

        <sequenceFlow id="sid-05a29cc5-7a04-4282-be89-4d83f943774b" sourceRef="sid-d0c54d06-2073-4018-8381-e5e43f1b5578"
                      targetRef="sid-0396a986-7e6b-4634-883b-1ee7db9aeb45"/>

        <serviceTask id="sid-c43c4370-4407-4746-893f-dcee3e4e9936"
                     activiti:exclusive="true"
                     name="Step2"
                     activiti:class="com.example.actividemo.ServiceTask2">
            <extensionElements>
                <activiti:field name="text2">
                    <activiti:string><![CDATA[test2]]></activiti:string>
                </activiti:field>
            </extensionElements>
        </serviceTask>

        <endEvent id="sid-665b6b28-9b81-4ab7-ba77-6eb50da3c810" name="End"/>
        <sequenceFlow id="sid-26493bea-97f7-44d4-b7ec-255266dcb8ab" sourceRef="sid-0396a986-7e6b-4634-883b-1ee7db9aeb45"
                      targetRef="sid-c43c4370-4407-4746-893f-dcee3e4e9936"/>
        <sequenceFlow id="sid-9f0f635b-4e97-4e95-b1fd-c9996bf659af" sourceRef="sid-c43c4370-4407-4746-893f-dcee3e4e9936"
                      targetRef="sid-665b6b28-9b81-4ab7-ba77-6eb50da3c810"/>
    </process>
</definitions>

其中,activiti:class="com.example.actividemo.ServiceTask1"activiti:class="com.example.actividemo.ServiceTask2"

对应到代码里:

package com.example.actividemo;


import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;

public class ServiceTask1 implements JavaDelegate {
    //流程变量
    private Expression text1;

    //重写委托的提交方法
    @Override
    public void execute(DelegateExecution execution) {
        System.out.println("serviceTask1 已经执行已经执行!");
        String value1 = (String) text1.getValue(execution);
        System.out.println(value1);
        execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
    }
}

package com.example.actividemo;


import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;

public class ServiceTask2 implements JavaDelegate {
    //流程变量
    private Expression text2;

    //重写委托的提交方法
    @Override
    public void execute(DelegateExecution execution) {
        System.out.println("serviceTask2 已经执行已经执行!");
        String value1 = (String) text2.getValue(execution);
        System.out.println(value1);
        execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
    }
}

Spring Boot 集成 Activiti 项目实战

创建 Spring Boot 工程,目录结构如下:

.
├── HELP.md
├── activi-demo.iml
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
    ├── main
    │   ├── java
    │   │   └── com
    │   │       └── example
    │   │           └── actividemo
    │   │               ├── ActivitiController.java
    │   │               ├── ActivityConsumerService.java
    │   │               ├── ActivityConsumerServiceImpl.java
    │   │               ├── Application.java
    │   │               ├── ServiceTask1.java
    │   │               └── ServiceTask2.java
    │   └── resources
    │       ├── application.properties
    │       ├── static
    │       ├── templates
    │       └── test01.bpmn20.xml
    └── test
        └── java
            └── com
                └── example
                    └── actividemo
                        └── ApplicationTests.java

14 directories, 14 files

源代码如下:

ActivitiController

package com.example.actividemo;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/activiti")
public class ActivitiController {

    @Autowired
    private ActivityConsumerService activityConsumerService;

    /**
     * 注册流程
     *
     * @return
     */
    @RequestMapping("/createDeployment")
    public Boolean createDeployment() {
        return activityConsumerService.createDeployment();
    }

    /**
     * 启动流程
     *
     * @return
     */
    @RequestMapping("/startActivityDemo")
    public Boolean startActivityDemo() {
        return activityConsumerService.startActivityDemo("test01");
    }

    /**
     * 获取待办
     *
     * @return
     */
    @RequestMapping("/getTaskList")
    public List getTaskList() {
        return activityConsumerService.getTaskList();
    }

    /**
     * 提交
     *
     * @param taskId
     * @return
     */
    @RequestMapping("/complete")
    public boolean complete(String taskId) {
        return activityConsumerService.complete(taskId);
    }

    /**
     * 根据流程id直接结束流程
     *
     * @return
     * @paramru
     */
    @RequestMapping("/deleteProcessInstance")
    public boolean deleteProcessInstance(String runId) {
        return activityConsumerService.deleteProcessInstance(runId);
    }


}

ActivityConsumerService

package com.example.actividemo;


import java.util.List;

public interface ActivityConsumerService {
    boolean createDeployment();

    boolean startActivityDemo(String key);

    List getTaskList();

    boolean complete(String taskId);

    boolean deleteProcessInstance(String runId);
}

ActivityConsumerServiceImpl

package com.example.actividemo;


import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.DeploymentBuilder;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service("activityService")
public class ActivityConsumerServiceImpl implements ActivityConsumerService {

    @Autowired
    private RuntimeService runtimeService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RepositoryService repositoryService;

    /**
     * 注册一个流程
     *
     * @return
     */
    @Override
    public boolean createDeployment() {
        DeploymentBuilder builder = repositoryService.createDeployment();
        builder.addClasspathResource("test01.bpmn20.xml");
        builder.deploy();
        return true;
    }

    /**
     * 查询待办
     *
     * @return
     */
    public List getTaskList() {
        return historyService.createHistoricActivityInstanceQuery().list();
    }


    /**
     * 根据流程key开启一个流程
     *
     * @param key
     * @return
     */
    @Override
    public boolean startActivityDemo(String key) {
        ProcessInstance test01 = runtimeService.startProcessInstanceByKey(key);
        String id = test01.getId();
        System.out.println("流程id=" + id);
        return true;
    }

    /**
     * 根据任务id提交任务
     *
     * @param taskId
     * @return
     */
    @Override
    public boolean complete(String taskId) {
        taskService.complete(taskId);
        return true;
    }

    /**
     * 根据流程id直接结束流程
     *
     * @param runId
     * @return
     */
    @Override
    public boolean deleteProcessInstance(String runId) {
        runtimeService.deleteProcessInstance(runId, "结束");
        return true;
    }


}

Application

package com.example.actividemo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;


@SpringBootApplication(exclude = {
        org.activiti.spring.boot.SecurityAutoConfiguration.class
})
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

ServiceTask1 、ServiceTask2

package com.example.actividemo;


import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;

public class ServiceTask1 implements JavaDelegate {
    //流程变量
    private Expression text1;

    //重写委托的提交方法
    @Override
    public void execute(DelegateExecution execution) {
        System.out.println("serviceTask1 已经执行已经执行!");
        String value1 = (String) text1.getValue(execution);
        System.out.println(value1);
        execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
    }
}

package com.example.actividemo;


import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.Expression;
import org.activiti.engine.delegate.JavaDelegate;

public class ServiceTask2 implements JavaDelegate {
    //流程变量
    private Expression text2;

    //重写委托的提交方法
    @Override
    public void execute(DelegateExecution execution) {
        System.out.println("serviceTask2 已经执行已经执行!");
        String value1 = (String) text2.getValue(execution);
        System.out.println(value1);
        execution.setVariable("var1", new StringBuffer(value1).reverse().toString());
    }
}

项目配置文件 application.properties

server.port=8080
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/activi_demo?useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=88888888
spring.activiti.check-process-definitions=false
spring.activiti.process-definition-location-prefix=classpath:*
spring.activiti.process-definition-location-suffixes=.bpmn20.xml

Maven 项目配置文件 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.1</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>activi-demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>activi-demo</name>
    <description>Demo project for Spring Boot</description>
    <properties>
        <java.version>1.8</java.version>
        <activiti.version>6.0.0</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>

        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter-basic</artifactId>
            <version>${activiti.version}</version>
        </dependency>

        <!-- Activiti 流程图 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-common-rest</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <!-- Activiti 在线设计 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-modeler</artifactId>
            <version>5.22.0</version>
            <exclusions>
                <exclusion>
                    <artifactId>spring-beans</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-context</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-core</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-tx</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-web</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-security-config</artifactId>
                    <groupId>org.springframework.security</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>spring-security-core</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-webmvc</artifactId>
                    <groupId>org.springframework</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>activation</artifactId>
                    <groupId>javax.activation</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>commons-io</artifactId>
                    <groupId>commons-io</groupId>
                </exclusion>
            </exclusions>
        </dependency>


        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

运行测试

先部署任务:http://127.0.0.1:8080/activiti/createDeployment

然后启动工作流实例:http://127.0.0.1:8080/activiti/startActivityDemo

运行输出:

serviceTask1 已经执行已经执行!
test1
serviceTask2 已经执行已经执行!
test2
流程id=7501

查看历史流程:http://127.0.0.1:8080/activiti/getTaskList

[
  {
    "id": "10003",
    "processInstanceId": "10001",
    "processDefinitionId": "test01:3:5044",
    "startTime": "2021-06-13T07:20:19.009+00:00",
    "endTime": "2021-06-13T07:20:19.010+00:00",
    "durationInMillis": 1,
    "deleteReason": null,
    "activityId": "sid-d0c54d06-2073-4018-8381-e5e43f1b5578",
    "activityName": "Start",
    "activityType": "startEvent",
    "executionId": "10002",
    "assignee": null,
    "taskId": null,
    "calledProcessInstanceId": null,
    "tenantId": "",
    "persistentState": {
      "executionId": "10002",
      "durationInMillis": 1,
      "endTime": "2021-06-13T07:20:19.010+00:00",
      "assignee": null,
      "deleteReason": null
    },
    "time": "2021-06-13T07:20:19.009+00:00",
    "inserted": false,
    "deleted": false,
    "updated": false
  },
  ...
,
  {
    "id": "7514",
    "processInstanceId": "7508",
    "processDefinitionId": "test01:3:5044",
    "startTime": "2021-06-13T06:47:16.733+00:00",
    "endTime": "2021-06-13T06:47:16.733+00:00",
    "durationInMillis": 0,
    "deleteReason": null,
    "activityId": "sid-665b6b28-9b81-4ab7-ba77-6eb50da3c810",
    "activityName": "End",
    "activityType": "endEvent",
    "executionId": "7509",
    "assignee": null,
    "taskId": null,
    "calledProcessInstanceId": null,
    "tenantId": "",
    "persistentState": {
      "executionId": "7509",
      "durationInMillis": 0,
      "endTime": "2021-06-13T06:47:16.733+00:00",
      "assignee": null,
      "deleteReason": null
    },
    "time": "2021-06-13T06:47:16.733+00:00",
    "inserted": false,
    "deleted": false,
    "updated": false
  }
]

工作流的数据库表数据:

数据库共28张表。一些比较重要的表有:

  1. act_ru_execution 执行对象表
  2. act_ru_task 用户任务表
  3. act_hi_actinst 活动节点历史表
  4. act_hi_procinst 流程实例历史表
  5. act_hi_taskinst 历史任务表

参考资料

https://www.cnblogs.com/qq376324789/p/12023530.html https://www.jianshu.com/p/972613558ba1

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Activiti 简介
    • Activiti 的核心服务组件
      • Activiti应用场景:
      • 业务流程模型 BPMN xml 配置文件
      • Spring Boot 集成 Activiti 项目实战
        • 源代码如下:
          • ActivitiController
          • ActivityConsumerService
          • ActivityConsumerServiceImpl
          • Application
          • ServiceTask1 、ServiceTask2
        • 项目配置文件 application.properties
          • Maven 项目配置文件 pom.xml
            • 运行测试
            • 参考资料
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档