关闭页面特效

activiti7 - SpringBoot集成

概念

BPM(Business Process Management)- 业务流程管理,是一种规范化的构造端到端的业务流程,以持续的提高组织业务效率。常见商业管理教育如EMBA、MBA等均将BPM包含在内。

BPMN(Business Process Model AndNotation)- 业务流程模型和符号 是由BPMI(BusinessProcess Management Initiative)开发的一套标准的业务流程建模符号,使用BPMN提供的符号可以创建业务流程。

img

当前使用最广泛工作流引擎对比:

技术组成 Activiti7.1 jBPM7.25 Camunda Flowable6.3.1
数据库持久层ORM MyBatis3.4.2 JPA2.2二次封装 Hibernate4.2.0 JPA 2.2
持久化标准 JPA规范 JPA规范 JPA规范 JPA规范
事务管理 MyBatis机制/Spring事务控制 Bitronix,基于JTA事务管理 hibernate机制/Spring事务控制 hibernate机制,Spring事务控制
分布式事务 MyBatis机制/Spring事务控制 Bitronix,基于JTA事务管理 补偿机制,SAGA 模式
数据库连接方式 Jdbc/DataSource Jdbc/DataSource Jdbc/DataSource Jdbc/DataSource
支持数据库 Oracle、SQL Server、MySQL Oracle、SQL Server、MySQL Oracle、SQL Server、MySQL、db2 Oracle、SQL Server、MySQL、db2
设计模式 Command模式、观察者模式等
内部服务通讯 Service间通过API调用 基于Apache Mina异步通讯 Service间通过API调用 Service间通过API调用
集成接口 SOAP、Mule、RESTful 消息通讯 SOAP、Mule、RESTful SOAP、Mule、RESTful
支持的流程格式 BPMN2、xPDL、jPDL等 目前仅只支持BPMN2 xml BPMN2、xPDL、jPDL等 BPMN2、xPDL、jPDL等
引擎核心 PVM(流程虚拟机) Drools PVM
架构 spring boot 2.1.2, spring 5.1.4 Drools Flow activiti5 spring boot 1.5,spring 4.3, spring.security 4.2
支持J2EE 兼容 天然支持EJB,J2EE 兼容 兼容
技术前身 jBPM3、jBPM4 Drools Flow activiti5 activiti5
API文档 swagger1.5 swagger1.5
日志 slf4j1.7门面,logback1.2.3 slf4j1.5门面, log4j slf4j1.7门面,logback1.2.3 slf4j1.7门面
所属公司 Alfresco jBoss.org Camunda Flowable

1|0表结构


表前缀规则

act_ge_ 通用数据表,ge是general的缩写

act_hi_ 历史数据表,hi是history的缩写,对应 HistoryService 接口

act_id_ 身份数据表,id是identity的缩写,对应 IdentityService 接口

act_re_ 流程存储表,re是repository的缩写,对应 RepositoryService 接口,存储流程部署和流程定义等静态数据

act_ru_ 运行时数据表,ru是runtime的缩写,对应 RuntimeService 接口和 TaskService 接口,存储流程实例和用户任务等动态数据

img

2|0设计架构


img

2|1服务接口


service名称 service作用
RepositoryService activiti的资源管理类
RuntimeService activiti的流程运行管理类
TaskService activiti的任务管理类
HistoryService activiti的历史管理类
ManagerService activiti的引擎管理类

2|2任务监听


任务监听器是发生对应的任务相关事件时执行自定义 java 逻辑 或表达式。 任务相当事件包括:

Create:任务创建后触发

Assignment:任务分配后触发

Delete:任务完成后触发

All:所有事件发生都触发

定义任务监听类,且类必须实现 org.activiti.engine.delegate.TaskListener 接口

public class MyTaskListener implements TaskListener { @Override public void notify(DelegateTask delegateTask) { //业务代码 } }

2|3生命周期


1 onCreate() :当一个Activity第一次启动时调用,表示一个Activity对象被创建一般情况下,我们会在该方法中做一些初始化的工作(初始化组件,设置事件监听,填充主布局,其他数据) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); } 2 onStart() :在onCreate方法之后调用,该方法用于显示界面,完成后我们可以看见界面,但还不能进行交互 @Override protected void onStart() { super.onStart(); } 3 onRestart() : 在当前Activity从停止状态重新被显示时会调用,接着会调用onStart--onResume @Override protected void onStart() { super.onStart(); } 4 onResume() :在onStart方法之后被调用,此方法完成后,界面可以进行交互,此时,Activity进入运行状态。该状态下可以实现还原状态的操作 @Override protected void onResume() { super.onResume(); } 5 onPause() :当前Activity被另一个Activity不完全覆盖时被调用(或被一个窗口模式的Activity覆盖),此时Activity进入暂停状态,该状态下,如果设备内存不足时有可能被销毁 :当覆盖当前Activity的另一个窗口模式的Activity出栈,此时会调用onResume方法,让Activity重新进入运行状态,该状态下可以保存Activity的状态,已在还原时继续执行 @Override protected void onPause() { super.onPause(); } 6 onStop() :当前Activity被完全覆盖后被调用,此时Activity已经看不见,Activity进入停止状态,该状态下,如果设备内存不足时有可能被销毁 当前Activity重新显示时,会调用onReStart----onStart----onResume @Override protected void onStop() { super.onStop(); } 7 onDestory() :当Activity被出栈,销毁时调用,表示当前Activity进入killed状态,那么我们一般在该方法进行资源释放工作 @Override protected void onDestroy() { super.onDestroy(); }

3|0项目集成


maven引入

<!-- 工作流activiti --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-spring-boot-starter</artifactId> <exclusions> <exclusion> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> </exclusion> </exclusions> </dependency> <!-- 生成流程图 --> <dependency> <groupId>org.activiti</groupId> <artifactId>activiti-image-generator</artifactId> </dependency>

注意:排除activiti自带的mybatis,防止与项目的mybatis冲突

yml配置

spring: activiti: #自动更新数据库结构 database-schema-update: true #activiti7默认不生成历史信息表,开启历史表 db-history-used: true #记录历史等级 可配置的历史级别有none, activity, audit, full #none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。 #activity:级别高于none,保存流程实例与流程行为,其他数据不保存。 #audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。 #full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。 history-level: full #自动检查、部署流程定义文件 启动时自动部署定义的流程 check-process-definitions: true # asyncExecutorActivate是指activiti在流程引擎启动就激活AsyncExecutor,异步:true-开启(默认)、false-关闭 async-executor-activate: true #流程定义文件存放目录,要具体到某个目录 process-definition-location-prefix: classpath:/processes/ #process-definition-location-suffixes: #流程文件格式 # - **.bpmn20.xml # - **.bpmn main: allow-bean-definition-overriding: true

注意: 启动如果bean生成失败,添加allow-bean-definition-overriding:true 允许bean被覆盖解决

执行流程代码

  1. 代码流程从发布-执行-完成-结束任务
@GetMapping("/publishList") public AjaxResult publishList() { List<ProcessDefinition> list = repositoryService .createProcessDefinitionQuery() .orderByProcessDefinitionVersion() .desc() .list(); for (ProcessDefinition item : list) { System.out.println("========"); System.out.println(item.getDeploymentId()); System.out.println(item.getId()); System.out.println(item.getKey()); System.out.println(item.getName()); } return AjaxResult.success(); } /** * 开启流程 * * @return */ @GetMapping("/startProcess") public AjaxResult startProcess(@RequestParam("key") String key) { ProcessInstance processInstance = runtimeService .startProcessInstanceByKey(key); if (processInstance != null) { System.out.println("============="); System.out.println(processInstance.getName()); System.out.println(processInstance.getProcessDefinitionKey()); System.out.println(processInstance.getId()); } return AjaxResult.success(); } /** * 查询正在运行的流程列表 * * @return */ @GetMapping("/runningList") public AjaxResult runningList(@RequestParam("instanceId") String instanceId, @RequestParam("key") String key) { List<ProcessInstance> list = runtimeService .createProcessInstanceQuery() .processInstanceId(instanceId) .processDefinitionKey(key) .list(); list.forEach(item -> { System.out.println("============"); System.out.println(item.getBusinessKey()); System.out.println(item.getDeploymentId()); System.out.println(item.getStartTime()); System.out.println(item.getProcessDefinitionKey()); System.out.println(item.getName()); }); return AjaxResult.success(); } /** * 查询任务并且完成 * * @param instanceId * @param key * @param assignee * @return */ @GetMapping("accomplishTask") public AjaxResult accomplishTask(@RequestParam("instanceId") String instanceId, @RequestParam("key") String key, @RequestParam("assignee") String assignee) { List<Task> list = taskService.createTaskQuery() .processDefinitionKey(key) .taskAssignee(assignee) .processInstanceId(instanceId) .list(); // 设置任务id // taskService.setVariableLocal("862e5029-31e4-11ed-ab1a-005056c00008", "num", "4"); // executionId 就当是processInstanceId // runtimeService.setVariableLocal("862b1bd5-31e4-11ed-ab1a-005056c00008", "num", 3); for (int i = 0; i < list.size(); i++) { Task task = list.get(i); // taskService.complete(task.getId()); System.out.println("=========="); System.out.println(task.getId()); System.out.println(task.getName()); System.out.println(task.getAssignee()); System.out.println(task.getProcessDefinitionId()); System.out.println(task.getProcessInstanceId()); System.out.println(task.getTaskDefinitionKey()); System.out.println(task.getExecutionId()); } return AjaxResult.success(); } /** * 判断进程是否结束 * * @param instanceId * @return */ @GetMapping("ProcessFinish") public AjaxResult ProcessFinish(@RequestParam String instanceId) { HistoricProcessInstance historicProcessInstance = historyService .createHistoricProcessInstanceQuery() .processInstanceId(instanceId) .singleResult(); if (historicProcessInstance != null) { if (historicProcessInstance.getEndTime() != null) { System.out.println("流程已结束!"); } else { System.out.println("流程未结束!"); } } else { System.out.println("流程不存在!"); } return AjaxResult.success(); } /** * 查看审批进程 * * @param instanceId * @return */ @GetMapping("viewApproval") public AjaxResult viewApproval(@RequestParam String instanceId) { // 历史节点 List<HistoricActivityInstance> list = historyService .createHistoricActivityInstanceQuery() .processInstanceId(instanceId) // .orderByActivityId() // .desc() .orderByHistoricActivityInstanceEndTime() .asc() .finished() // .unfinished() .list() .stream() .filter(item -> !StringUtils.containsAny(item.getActivityType(), "inclusiveGateway", "parallelGateway")) .collect(Collectors.toList()); // 历史变量 for (int i = 0; i < list.size(); i++) { System.out.println("========"); HistoricActivityInstance historicActivityInstance = list.get(i); // System.out.println(historicActivityInstance.getActivityId()); // _2 System.out.println(historicActivityInstance.getActivityName()); String taskId = historicActivityInstance.getTaskId(); System.out.println(taskId); String result = ""; if (StringUtils.isNotEmpty(taskId)) { HistoricVariableInstance historicVariableInstance = historyService.createHistoricVariableInstanceQuery().taskId(taskId).variableName("result").singleResult(); result = (String) historicVariableInstance.getValue(); // 已经经过的节点不适用该方法查询变量 // result = (String) taskService.getVariableLocal(taskId, "result"); } System.out.println(historicActivityInstance.getAssignee() + "----" + result); System.out.println(historicActivityInstance.getStartTime()); System.out.println(historicActivityInstance.getEndTime()); // System.out.println("ExecutionId:" + historicActivityInstance.getExecutionId()); // System.out.println("ProcessInstanceId:" + historicActivityInstance.getProcessInstanceId()); // System.out.println(historicActivityInstance.getActivityType()); // userTask } return AjaxResult.success(); } /** * 申请任务 * @param key * @param assignee * @return */ @GetMapping("applyTask") public AjaxResult applyTask(@RequestParam("key") String key, @RequestParam("assignee") String assignee){ if (StringUtils.isBlank(key)) { throw new RuntimeException("key不能为空!"); } if (StringUtils.isBlank(assignee)) { throw new RuntimeException("assignee不能为空!"); } Task task = taskService.createTaskQuery() .taskCandidateUser(assignee) // .taskId(taskId) .processInstanceBusinessKey(key) .singleResult(); if (task != null) { taskService.claim(task.getId(), assignee); log.info(assignee + "申领到了任务!"); } return AjaxResult.success(); } /** * 放弃任务 * @param key * @param assignee * @return */ @GetMapping("abandonTask") public AjaxResult abandonTask(@RequestParam("key") String key, @RequestParam("assignee") String assignee){ if (StringUtils.isBlank(key)) { throw new RuntimeException("businessKey不能为空!"); } if (StringUtils.isBlank(assignee)) { throw new RuntimeException("assignee不能为空!"); } Task task = taskService.createTaskQuery() .taskAssignee(assignee) // .taskId(taskId) .processInstanceBusinessKey(key) .singleResult(); if (task != null) { taskService.setAssignee(task.getId(), null); log.info(assignee + "放弃了任务!"); } return AjaxResult.success(); }

__EOF__

作  者走马观花
出  处https://www.cnblogs.com/cool-fun/p/17165234.html
关于博主:编程路上的小学生,热爱技术,喜欢专研。评论和私信会在第一时间回复。或者直接私信我。
版权声明:署名 - 非商业性使用 - 禁止演绎,协议普通文本 | 协议法律文本
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!

posted @   让人生留下足迹  阅读(338)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
历史上的今天:
2020-02-28 window系统mysql安装后获取默认密码
点击右上角即可分享
微信分享提示