本文就不对activiti做解释,下面直接看项目集成
以下顺序方面根据我的理解来,可以先从第二章看,再看第一张与第三章
增加activiti表的API,备注用。
目录
一、springboot2.X集成activiti
1.1. 引入jar包
1.2. 创建启动类(componentScan是自己项目持久化模板,可以直接删掉)
1.3. 配置application.yml
1.4. 启动可能出现的错误
二、编写测试流程
三、编写bpmn
1.1 设置编码
1.2 创建bpmn
1.3 编写逻辑
四、activiti数据库表概览
1.1 说明
1.2 概览
1.2.1 Activiti数据表清单:
4.0.0
enn-activiti
enn.activiti
1.1.1-SNAPSHOT
jar
org.springframework.boot
spring-boot-starter-parent
2.0.4.RELEASE
org.springframework.boot
spring-boot-starter-web
org.hibernate.validator
hibernate-validator
org.apache.logging.log4j
log4j-to-slf4j
org.slf4j
jul-to-slf4j
org.springframework.boot
spring-boot-starter-tomcat
org.activiti
activiti-spring-boot-starter-basic
6.0.0
javax.persistence
persistence-api
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-thymeleaf
org.springframework.boot
spring-boot-starter-test
test
local
local
true
dev
dev
enn-activiti
org.apache.maven.plugins
maven-compiler-plugin
${java.version}
org.springframework.boot
spring-boot-maven-plugin
org.apache.maven.plugins
maven-surefire-plugin
true
true
@SpringBootApplication(exclude = SecurityAutoConfiguration.class)
@ComponentScan(basePackages = {"enn.activiti","enn.base.redis.cluster",
"enn.base.utils","enn.base.mysql.ordinary","enn.base.mysql.dao"})
@EnableAsync
public class Application {
static ConfigurableApplicationContext applicationContext;
public static void main(String[] args) {
applicationContext = SpringApplication.run(Application.class, args);
}
}
# \u670D\u52A1\u7AEF\u53E3
server:
port: ${SERVER_PORT:8082}
#\u6570\u636E\u5E93\u94FE\u63A5\u914D\u7F6E
spring:
datasource:
name: ecityposition
type: com.alibaba.druid.pool.DruidDataSource
filters: stat
url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.jdbc.Driver
username: root
password: root
#配置初始化大小/最小/最大
initial-size: 1
min-idle: 1
max-active: 20
#获取连接等待超时时间
max-wait: 60000
#间隔多久进行一次检测,检测需要关闭的空闲连接
time-between-eviction-runs-millis: 60000
#一个连接在池中最小生存的时间
min-evictable-idle-time-millis: 300000
validation-query: SELECT 'x'
test-while-idle: true
test-on-borrow: false
test-on-return: false
#打开PSCache,并指定每个连接上PSCache的大小。oracle设为true,mysql设为false。分库分表较多推荐设置为false
pool-prepared-statements: false
max-pool-prepared-statement-per-connection-size: 20
jpa:
properties:
hibernate:
hbm2ddl:
auto: update
jackson:
date-format: yyyy-MM-dd HH:mm:ss
time-zone: GMT+8
activiti:
check-process-definitions: false
database-schema-update: true
上述已经解决,直接启动没有问题
1.4.1 如果项目使用myibatis,则需要再依赖中排除persistence-api,否则会以下的错误:
Consider defining a bean of type 'javax.persistence.EntityManagerFactory' in your configuration.
1.4.2 在配置文件中设置不扫描processes文件包
如果还没有建bpmn模型,则会出现如下错误:
java.io.FileNotFoundException: class path resource [processes/] cannot be resolved to URL because it does not exist
另外,database-schema-update属性,可选值为: false,true,create-drop,drop-create,默认为true。
为true表示activiti会对数据库中的表进行更新操作,如果不存在,则进行创建。
1.4.3 在启动类上排除SecurityAutoConfiguration类,否则报:
java.lang.ArrayStoreException: sun.reflect.annotation.TypeNotPresentExceptionProxy
因为GlobalAuthenticationConfigurerAdapter 是spring-boot-starter-security 依赖中的属于安全配置类, 而 引入的activiti-spring-boot-starter-basic 依赖中存在了一个自动安全配置类, 两个安全配置, 所以排除掉 activiti-spring-boot-starter-basic中的安全配置类 SecurityAutoConfiguration
写的较为简单,但可通过如下进行测试,理解bpmn
import enn.activiti.entity.vo.dbDict.DbDictTreeVo;
import enn.activiti.entity.vo.dbDict.DbDictVo;
import enn.activiti.service.ActivityConsumerService;
import enn.activiti.utils.DictUtils;
import enn.activiti.utils.common.ResultTreeBean;
import enn.base.utils.web.ActionResult;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @auther: liuxianling
* @date: 2018/12/2 21:38
* @description:
*/
@RestController
@RequestMapping("/api/activiti")
@Api(value = "/ActivityConsumerController", description = "ActivityConsumerController")
public class ActivityConsumerController {
private static final Logger logger = LoggerFactory.getLogger(DbDictController.class);
@Resource
ActivityConsumerService activityConsumerService;
/**
* 1:启动流程实例
*/
@ApiOperation(value = "启动流程实例", notes = "启动流程实例")
@GetMapping("/testStartProcessInstance")
public void testStartProcessInstance(@RequestParam("procdefId") String procdefId){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService()
.startProcessInstanceById(procdefId); //这个是查看数据库中act_re_procdef表
}
/**
* 2.完成请假申请
*/
@ApiOperation(value = "完成请假申请", notes = "完成请假申请")
@GetMapping("/testQingjia")
public void testQingjia(String taskId){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete(taskId); //查看act_ru_task表
}
/**
* 3.班主任查询当前任务
*/
@ApiOperation(value = "班主任查询当前任务", notes = "班主任查询当前任务")
@GetMapping("/taskAssignee")
public void testQueryTask(String taskAssignee){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List tasks = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee(taskAssignee)
.list();
for (Task task : tasks) {
System.out.println(task.getName());
}
}
/**
* 4.班主任完成任务
*/
@ApiOperation(value = "班主任完成任务", notes = "班主任完成任务")
@GetMapping("/testFinishTask_manager")
public void testFinishTask_manager(String taskId){
ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
engine.getTaskService()
.complete(taskId); //查看act_ru_task数据表
}
/**
* 5.教务处主任完成任务
*/
@ApiOperation(value = "教务处主任完成任务", notes = "教务处主任完成任务")
@GetMapping("/testFinishTask_Boss")
public void testFinishTask_Boss(String taskId){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete(taskId); //查看act_ru_task数据表
}
}
1. StartEvent-->点击空白处,定义流程名称-->UserTask(请假流程,定义请假人)-->UserTask(班主任审批,定义班主任)-->userTask(教导处审批,定义教导处)-->EndEvent结束流程,如图所示:
Activiti工作流总共包含23张数据表,所有的表名默认以“ACT_”开头。
并且表名的第二部分用两个字母表明表的用例,而这个用例也基本上跟Service API匹配。
u ACT_GE_* : “GE”代表“General”(通用),用在各种情况下;
u ACT_HI_* : “HI”代表“History”(历史),这些表中保存的都是历史数据,比如执行过的流程实例、变量、任务,等等。Activit默认提供了4种历史级别:
Ø none: 不保存任何历史记录,可以提高系统性能;
Ø activity:保存所有的流程实例、任务、活动信息;
Ø audit:也是Activiti的默认级别,保存所有的流程实例、任务、活动、表单属性;
Ø full:最完整的历史记录,除了包含audit级别的信息之外还能保存详细,例如:流程变量。
对于几种级别根据对功能的要求选择,如果需要日后跟踪详细可以开启full。
Acitiviti数据库中表的命名都是以ACT_开头的。第二部分是一个两个字符用例表的标识。此用例大体与服务API是匹配的。
l ACT_RE_*:’RE’表示repository。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。
l ACT_RU_*:’RU’表示runtime。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。Activiti只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。
l ACT_ID_*:’ID’表示identity。这些表包含标识的信息,如用户,用户组,等等。
l ACT_HI_*:’HI’表示history。就是这些表包含着历史的相关数据,如结束的流程实例,变量,任务,等等。
l ACT_GE_*:普通数据,各种情况都使用的数据。
表分类 |
表名 |
解释 |
一般数据 |
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_RE_DEPLOYMENT |
部署单元信息,用来存储部署时需要持久化保存下来的信息 |
ACT_RE_MODEL |
模型信息 |
|
ACT_RE_PROCDEF |
已部署的流程定义,业务流程定义数据表 此表和ACT_RE_DEPLOYMENT是多对一的关系,即, 一个部署的bar包里可能包含多个流程定义文件, 每个流程定义文件都会有一条记录在ACT_REPROCDEF表内, 每个流程定义的数据,都会对于ACT_GE_BYTEARRAY表内 的一个资源文件和PNG图片文件。和ACT_GE_BYTEARRAY 的关联是通过程序用ACT_GE_BYTEARRAY.NAME与 ACT_RE_PROCDEF.NAME_完成的,在数据库表结构中没有体现 |
|
运行实例表 |
ACT_RU_EVENT_SUBSCR |
运行时事件 |
ACT_RU_EXECUTION |
运行时流程执行实例 |
|
ACT_RU_IDENTITYLINK |
运行时用户关系信息,主要存储当前节点参与者的信息。 |
|
ACT_RU_JOB |
运行时作业,运行时定时任务数据表 |
|
ACT_RU_TASK |
运行时任务 |
|
ACT_RU_VARIABLE |
运行时变量表 |
注:
l 流程文件部署主要涉及到3个表,分别是:ACT_GE_BYTEARRAY、ACT_RE_DEPLOYMENT、ACT_RE_PROCDEF。主要完成“部署包”-->“流程定义文件”-->“所有包内文件”的解析部署关系。从表结构中可以看出,流程定义的元素需要每次从数据库加载并解析,因为流程定义的元素没有转化成数据库表来完成,当然流程元素解析后是放在缓存中的,具体的还需要后面详细研究。
l 流程定义中的java类文件不保存在数据库里 。
l 组织机构的管理相对较弱,如果要纳入单点登录体系内还需要改造完成,具体改造方法有待研究。
l 运行时对象的执行与数据库记录之间的关系需要继续研究
l 历史数据的保存及作用需要继续研究。
activiti-administrator
自带的用户管理系统,维护用户和组,需要配置数据连接参数,在activiti-administrator\WEB-INF\applicationContext.xml中,并加入JDBC驱动包。
activiti-cycle
PVM活动检测的,由activiti-rest提供服务,不需配置。
activiti-explorer
可以查看用户任务和启动流程,由activiti-rest提供服务,不需配置。
activiti-kickstart
简单的点对点流程定义维护工具,需要配置数据连接,把activiti.cfg.xml文件放在classes下,并加入驱动包。
activiti-modeler
在线编辑和维护流程定义的工具,最后以文件夹方式部署,需要配置activiti-modeler\WEB-INF\classes\configuration.properties文件。
activiti-probe
PVM的观测服务,由activiti-rest提供服务,不需配置,可以查看deployment、processdefinition、processinstance、database。
activiti-rest
其他几个应用的服务提供者,需要配置数据连接,把activiti.cfg.xml文件放在classes下,并加入驱动包。
五,表结构变化
参考:https://blog.csdn.net/cs_hnu_scw/article/details/79059965
https://blog.csdn.net/hj7jay/article/details/51302829