使用STS+Activiti来切入工作流开发

这里实验工作流开发:使用STS作为IDE,使用Activiti作为工作流框架。

安装和使用STS的方法,此处不再赘述。


1、自动创建工作流表

创建一个Springboot项目,

使用STS+Activiti来切入工作流开发

修改POM文件:

<?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.1.13.RELEASE</version>

<relativePath/> <!-- lookup parent from repository -->

</parent>

<groupId>com.edison</groupId>

<artifactId>activiti-test</artifactId>

<version>0.0.1-SNAPSHOT</version>

<name>activiti-test</name>

<description>Demo project for activiti</description>


<properties>

<java.version>1.8</java.version>

</properties>


<dependencies>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter</artifactId>

</dependency>

<!-- activiti -->

<dependency>

<groupId>org.activiti</groupId>

<artifactId>activiti-spring-boot-starter-basic</artifactId>

<version>6.0.0</version>

</dependency>


<!-- mybatis -->

<dependency>

<groupId>org.mybatis.spring.boot</groupId>

<artifactId>mybatis-spring-boot-starter</artifactId>

<version>1.3.2</version>

</dependency>


<!--swagger -->

<dependency>

<groupId>io.springfox</groupId>

<artifactId>springfox-swagger2</artifactId>

<version>2.8.0</version>

</dependency>

<dependency>

<groupId>io.springfox</groupId>

<artifactId>springfox-swagger-ui</artifactId>

<version>2.8.0</version>

</dependency>

<!-- mysql -->

<dependency>

<groupId>mysql</groupId>

<artifactId>mysql-connector-java</artifactId>

<scope>runtime</scope>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-test</artifactId>

<scope>test</scope>

<exclusions>

<exclusion>

<groupId>org.junit.vintage</groupId>

<artifactId>junit-vintage-engine</artifactId>

</exclusion>

</exclusions>

</dependency>

</dependencies>


<build>

<plugins>

<plugin>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-maven-plugin</artifactId>

</plugin>

</plugins>

</build>


</project>


修改入口类:

package com.edison.demo;


import org.activiti.spring.boot.SecurityAutoConfiguration;

import org.mybatis.spring.annotation.MapperScan;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.ComponentScan;


@ComponentScan(basePackages = {"com.edison.demo"})

@MapperScan(basePackages = {"com.edison.demo"})

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)

public class ActivitiTestApplication {


public static void main(String[] args) {

SpringApplication.run(ActivitiTestApplication.class, args);

}


}


修改application.properties:

server.port=8080

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.url=jdbc:mysql://localhost:3306/db_activiti?serverTimezone=Asia/Chongqing&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false&verifyServerCertificate=false&autoReconnct=true&autoReconnectForPools=true&allowMultiQueries=true

spring.datasource.username=root

spring.datasource.password=radar

mybatis.mapper-locations=classpath:mapper/*.xml

mybatis.type-aliases-package=com.edison.model

spring.activiti.check-process-definitions=false



直接在STS中启动微服务,

使用STS+Activiti来切入工作流开发

该服务会创建28张表,

使用STS+Activiti来切入工作流开发

如下:

表分类

表名称

表含义

事件

act_evt_log

事件处理日志表

一般数据

act_ge_bytearray

通用的流程定义和流程资源


act_ge_property

系统相关属性

流程历史记录

act_hi_actinst

历史的流程实例


act_hi_attachment

历史的流程附件


act_hi_comment

历史的说明性信息


act_hi_detail

历史的流程运行中的细节信息


act_hi_identitylink

历史的流程运行过程中用户关系


act_hi_procinst

历史的流程实例


act_hi_taskinst

历史的任务实例


act_hi_varinst

历史的流程运行中的变量信息

用户用户组表

act_id_group

身份信息-组信息


act_id_info

身份信息-组信息


act_id_membership

身份信息-用户和组关系的中间表


act_id_user

身份信息-用户信息


act_procdef_info

死信任务

流程定义表

act_re_deployment

部署单元信息


act_re_model

模型信息


act_re_procdef

已部署的流程定义

运行实例表

act_ru_deadletter_job

执行失败任务表


act_ru_event_subscr

运行时事件


act_ru_execution

运行时流程执行实例


act_ru_identitylink

运行时用户关系信息


act_ru_job

运行时作业


act_ru_suspended_job

运行时暂停任务


act_ru_task

运行时任务


act_ru_timer_job

运行时定时任务


act_ru_variable

运行时变量表


可能遇到的错误:

org.apache.ibatis.exceptions.PersistenceException:

### Error querying database.  Cause: java.sql.SQLSyntaxErrorException: Table 'db_activiti.act_ge_property' doesn't exist

### The error may exist in org/activiti/db/mapping/entity/Property.xml

 

解决方法:很可能在另外一个数据库中已经存在act_ge_property,把另外一个库中act相关的表删除后即可。


2、ACTIVITI工作流术语

(1) 业务流程

一个ProcessDefinition代表的业务流程。它用于定义流程中不同步骤的结构和行为。

(2) 流程定义

部署流程定义意味着将流程定义加载到Activiti数据库中。

(3) BPMN 2.0标准

流程定义主要由BPMN 2.0标准定义,也可以使用Java代码定义它们,定义的所有术语也可用作Java类。

(4) 流程process

一旦我们开始运行流程定义,就可以称为一个流程process。

(5)  processInstance

processInstance是ProcessDefinition一个执行实例。

(6) StartEvent

一个StartEvent与每一个业务流程有关,它表示该流程的切入点,同样,有一个EndEvent表示流程的结束。我们可以定义这些事件的条件。

(7) 任务

开始和结束之间的所有步骤(或元素)称为任务,任务可以是各种类型的。最常用的任务是UserTasks和ServiceTasks。

(8)服务

RepositoryService:帮助我们实现流程定义的部署。此服务会处理与流程定义相关的静态数据。
RuntimeService:管理 ProcessInstances(当前正在运行的流程)以及流程变量
TaskService:会跟踪 UserTasks,需要由用户手动执行的任务是Activiti API的核心。我们可以使用此服务创建任务,声明并完成任务,分配任务的受让人等。
FormService:是一项可选服务,它用于定义中开始表单和任务表单。
IdentityService:管理用户和组。
HistoryService:会跟踪Activiti Engine的历史记录。我们还可以设置不同的历史级别。
ManagementService:与元数据相关,在创建应用程序时通常不需要。
DynamicBpmnService:帮助我们在不重新部署的情况下更改流程中的任何内容。


3、增加设计器插件

在线安装:在STS中Help -> Install New SoftWare-> Add:

使用STS+Activiti来切入工作流开发


Name: Activiti Designer
Location: http://activiti.org/designer/update/

在线安装往往会失败。

 

离线安装:安装失败就使用离线下载,官方提示链接:

https://github.com/Activiti/Activiti-Designer/releases

下载地址:

https://www.activiti.org/designer/archived/activiti-designer-5.18.0.zip

但是这个文件不完整,还差文件,缺失的jar包在错误提示里面有,可以从mvnreprository.com中找到。

以下链接是已经测试通过的完整文件:

https://gitee.com/radarfyh/spring-cloud-test/tree/spring-cloud-test/activiti-test

如下图,activiti-designer-5.18.0.zip文件是官网下载的,plugins.zip里面是缺失的文件,解压后放入前一个zip中。

使用STS+Activiti来切入工作流开发

然后在STS中Help -> Install New SoftWare-> Add:

使用STS+Activiti来切入工作流开发

使用STS+Activiti来切入工作流开发

由此可以成功安装。

 

安装成功后,在new建项目的other目录下可以找到:

使用STS+Activiti来切入工作流开发


到preferences中修改设置:

使用STS+Activiti来切入工作流开发


4、入门项目

(1)新建Springboot项目,POM文件引入spring-boot-starter-web、angularjs、activiti-spring-boot-starter-basic、mysql-connector-java,如下:

<?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.1.13.RELEASE</version>

        <relativePath/> <!-- lookup parent from repository -->

    </parent>

    <groupId>com.edison</groupId>

    <artifactId>activiti-test6</artifactId>

    <version>0.0.1-SNAPSHOT</version>

    <name>activiti-test6</name>

    <description>测试初始工作流项目</description>

 

    <properties>

        <java.version>1.8</java.version>

    </properties>

 

    <dependencies>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>


        <dependency>

            <groupId>org.webjars</groupId>

            <artifactId>angularjs</artifactId>

            <version>1.7.2</version>

        </dependency>

 

        <dependency>

            <groupId>org.activiti</groupId>

            <artifactId>activiti-spring-boot-starter-basic</artifactId>

            <version>6.0.0</version>

        </dependency>

 

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

        </dependency>

    

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

    </dependencies>

 

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

 

</project>

(2)入口类修改为:

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)

@RestController

public class ActivitiTest6Application {

 

    public static void main(String[] args) {

        SpringApplication.run(ActivitiTest6Application.class, args);

    }

    @GetMapping("/test")

    public User sayHello(){

        System.out.println("----采用angularjs----");

        User user = new User();

        user.setName("admin");

        user.setPassword("123456");

        return user;

    }

}

(3)新增用户类:

public class User {

    String id;

    String name;

    String password;

    public String getId() {

        return id;

    }

    public void setId(String id) {

        this.id = id;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getPassword() {

        return password;

    }

    public void setPassword(String password) {

        this.password = password;

    }


}

(4)新增任务描述类:

public class TaskRepresentation {

private String id;

    private String name;

 

    public TaskRepresentation(String id, String name) {

        this.id = id;

        this.name = name;

    }

 

    public String getId() {

        return id;

    }

 

    public void setId(String id) {

        this.id = id;

    }

 

    public String getName() {

        return name;

    }

 

    public void setName(String name) {

        this.name = name;

    }

}

(5)新增服务类:

@Service

public class ActivitiService {

    @Autowired

    private RuntimeService runtimeService;

    @Autowired

    private TaskService taskService;

 

    public String start() {

        ProcessInstance instance = runtimeService.startProcessInstanceByKey("myProcess");

        return instance.getId();

    }

 

    public List<Task> getTask(String uid) {

        List<Task> tasks = taskService.createTaskQuery().taskAssignee(uid).list();

        return tasks;

    }

}

(6)新增控制类:

@RestController

@RequestMapping(value = "activiti")

public class ActivitiController {

    @Autowired

    private ActivitiService service;

 

    @RequestMapping(value = "start", method = RequestMethod.GET)

    public String start() {

        return service.start();

    }

 

    @RequestMapping(value = "task", method = RequestMethod.GET)

    public List<TaskRepresentation> getTask(@RequestParam(value = "uid") String uid) {

        List<Task> tasks = service.getTask(uid);

        List<TaskRepresentation> dtos = new ArrayList<>();

        for (Task task : tasks) {

            dtos.add(new TaskRepresentation(task.getId(), task.getName()));

        }

        return dtos;

    }

}

 

(7)新增审批流程(activiti diagram),如下:

使用STS+Activiti来切入工作流开发

 

其中流程id为myProcess,审批任务的审核者Assignee为admin。

 

(8)新增前端页面index.html:

<!DOCTYPE html>

<html lang="en">

<head>

<meta charset="UTF-8">

<title>流程测试首页</title>

</head>

<!--<script type="text/javascript" src="js/angular.js"></script>-->

<script type="text/javascript"

src="webjars/angularjs/1.7.2/angular.min.js"></script>

<script type="text/javascript" src="controller/userController.js"></script>

<body>

<h1>测试activiti</h1>

<div ng-app="myApp" >


    <div ng-controller="userController" ng-init="queryTasks()">

        <h2>待我审核的任务</h2>

        <table border="2">

            <tr>

                <td>id</td>

                <td>名称</td>

            </tr>

            <tr ng-repeat="vacTask in vacTaskList">

                <td>{{vacTask.id}}</td>

                <td>{{vacTask.name}}</td>

            </tr>

        </table>

        

        <h4>{{title}}{{number}}</h4>

        

    </div>

</div>

</body>

</html>

(9)新增angularjs的控制器userController.js:

var app=angular.module("myApp",[]);

app.controller("userController",function ($scope,$http) {

    $scope.vacTaskList = [];

    $scope.queryTasks = function () {

        $http.get(

            "/activiti/task?uid=admin"

        ).then(function (response) {

            $scope.vacTaskList = response.data;

            $scope.title = "任务数量为:";

            $scope.number=$scope.vacTaskList.length;

        })

    };

})

(10)新增配置文件application.yml,如下:

server:

  port: 8082

 

spring:

  datasource:

    url: jdbc:mysql://localhost:3306/act5?serverTimezone=Asia/Chongqing&useUnicode=true&characterEncoding=utf8&characterSetResults=utf8&useSSL=false&verifyServerCertificate=false&autoReconnct=true&autoReconnectForPools=true&allowMultiQueries=true

    driver-class-name: com.mysql.cj.jdbc.Driver

    username: root

    password: radar

 

  # activiti default configuration

  activiti:

    database-schema-update: true

    check-process-definitions: true

    process-definition-location-prefix: classpath:/processes/

# process-definition-location-suffixes:

# - **.bpmn

# - **.bpmn20.xml

    history-level: full

(11)使用chrome测试:

使用STS+Activiti来切入工作流开发


(12)可能遇到的错误

错误:Could not update Activiti database schema: unknown version from database: '6.0.0.4'

解决办法:删除以前的activiti表:

使用STS+Activiti来切入工作流开发


错误:Cannot instantiate interface org.springframework.context.ApplicationContextInitializer

 

详细提示:

[ERROR] Failed to execute goal org.springframework.boot:spring-boot-maven-plugin:2.0.4.RELEASE:run (default-cli) on project activiti-test1: An exception occurred while running. null: InvocationTargetException: Cannot instantiate interface org.springframework.context.ApplicationContextInitializer : org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer: org.springframework.core.KotlinDetector.isKotlinReflectPresent()Z -> [Help 1]


使用STS+Activiti来切入工作流开发

解决办法:编译通过后,这是使用mvn spring-boot:run出现的错误



错误:Description Resource Path Location Type

Failed to read artifact descriptor for com.fasterxml.jackson.core:jackson-core:jar:2.9.6

使用STS+Activiti来切入工作流开发


解决办法:这是POM提示的错误,在本地仓库中找到_remote.repositories,把其中两个的远程仓库指定为私服alfresco,或者其他服,例如私服nexus,*服central


使用STS+Activiti来切入工作流开发

如果项目太多,删除他们,只剩一个,这样可以解决各个项目之间的影响,猜测是STS的bug。STS的版本为:4.5.1.RELEASE



错误:

 

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'requestMappingHandlerMapping' defined in class path resource [org/springframework/web/servlet/config/annotation/DelegatingWebMvcConfiguration.class]: Invocation of init method failed; nested exception is java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy

 

......

java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy

 

 

解决方案:

在注解@SpringBootApplication后面加入exclude,如下:

@SpringBootApplication(exclude = SecurityAutoConfiguration.class)

注意import 的包不要错了,应该引入:

import org.activiti.spring.boot.SecurityAutoConfiguration;


上一篇:2021-03-01


下一篇:STS 开发WebApi