项目中需要用到工作流引擎来设计部分业务流程,框架选型最终选择了 Camunda7,关于 Camunda以及 Activity 等其他工作流 引擎的介绍及对比不再介绍,这里只介绍与现有
spring
boot项目的集成以及具体使用及配置
流程(PROCESS)
: 通过工具建模最终生成的BPMN文件,里面有整个流程的定义
可以根据需要引用版本,我这边用的是 7.18
需要3个maven依赖,分别是对应 流程引擎、Web管理平台、提供rest api操作接口包
<dependency > <groupId > org.camunda.bpm.springboot</groupId > <artifactId > camunda-bpm-spring-boot-starter</artifactId > <version > 7.18.0</version > </dependency > <dependency > <groupId > org.camunda.bpm.springboot</groupId > <artifactId > camunda-bpm-spring-boot-starter-rest</artifactId > <version > 7.18.0</version > </dependency > <dependency > <groupId > org.camunda.bpm.springboot</groupId > <artifactId > camunda-bpm-spring-boot-starter-webapp</artifactId > <version > 7.18.0</version > </dependency >
我这边使用的是
MySQL
,建了个新库 camunda(可自定义),启动后会自动生成所需表结构
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.7.3</version > <relativePath /> <!-- lookup parent from repository --> </parent > <groupId > com.example</groupId > <artifactId > camunda-demo</artifactId > <version > 0.0.1-SNAPSHOT</version > <name > camunda-demo</name > <description > camunda-demo</description > <properties > <java .version> 17</java.version > </properties > <dependencies > <dependency > <groupId > org.springframework.boot</groupId > <artifactId > spring-boot-starter</artifactId > </dependency > <dependency > <groupId > org.camunda.bpm.springboot</groupId > <artifactId > camunda-bpm-spring-boot-starter</artifactId > <version > 7.18.0</version > </dependency > <dependency > <groupId > org.camunda.bpm.springboot</groupId > <artifactId > camunda-bpm-spring-boot-starter-rest</artifactId > <version > 7.18.0</version > </dependency > <dependency > <groupId > org.camunda.bpm.springboot</groupId > <artifactId > camunda-bpm-spring-boot-starter-webapp</artifactId > <version > 7.18.0</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.32</version > </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 >
application.yml
server: port: 8081 # camunda登录信息配置 camunda.bpm: admin-user: id: admin #用户名 password:
123456 #密码 firstName: yu filter: create: All tasks # mysql连接信息 spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:8101/camunda username: root password: 123456 type: com.mysql.cj.jdbc.MysqlDataSource
准备好前置工作,启动后效果如下:
数据库表结构
启动后自动生成的表结构如下
大概有这么几个表模块,重要的详细介绍下:
这部分表示用户模块,配置文件里面的用户,信息就在此模块
表示流程历史记录
act_hi_actinst
: 执行的活动历史
service
public void startProcess () { ProcessInstance instance = runtimeService.startProcessInstanceByKey("key" ); System.out.println(instance.toString()); }public List<ProcessDefinition> findProcesses () { return repositoryService.createProcessDefinitionQuery().list(); }public List<Task> findTasks () { return taskService.createTaskQuery().list(); }
启动流程成功,说明问题不大,接下来详细业务改进。
下一篇介绍详细的业务集成及各种API(变量传递、自动任务)的使用
API使用
流程相关API
创建流程:
会同时创建第一个任务
ProcessInstance instance = runtimeService.startProcessInstanceByKey(processKey, params);
流程暂停后,再执行相关任务会报错,需要先重新激活任务
runtimeService.suspendProcessInstanceById(instance.getId());
重新激活流程
runtimeService.activateProcessInstanceById(instance.getId());
会同时删除任务
runtimeService.deleteProcessInstance(instance.getId(), "手动删除" );
以上都可以在流程历史表
act_hi_procinst
里查询
任务相关API
基于service的查询类,都可先构建一个 query,然后在附上查询条件,实例几个
List<ProcessDefinition> list = repositoryService.createProcessDefinitionQuery().list(); List<Task> list = taskService.createTaskQuery().taskAssignee("zhangsan" ).list(); List<ProcessInstance> instances = runtimeService.createProcessInstanceQuery().listPage(1 , 10 );
查询历史任务
List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery().list();
查询当前任务/分页
List<Task> list = taskService.createTaskQuery().orderByTaskCreateTime().desc().list();
大体思路是拿到当前的任务,及当前任务的上一个历史任务,然后重启
Task activeTask = taskService.createTaskQuery() .taskId(taskId) .active() .singleResult(); List<HistoricTaskInstance> historicTaskInstance = historyService.createHistoricTaskInstanceQuery() .processInstanceId(instanceId) .orderByHistoricActivityInstanceStartTime() .desc() .list(); List<HistoricTaskInstance> historicTaskInstances = historicTaskInstance.stream().filter(v -> !v.getTaskDefinitionKey().equals(activeTask.getTaskDefinitionKey())).toList(); Assert.notEmpty(historicTaskInstances, "当前已是初始任务!" ); HistoricTaskInstance curr = historicTaskInstances.get(0 ); runtimeService.createProcessInstanceModification(instanceId) .cancelAllForActivity(activeTask.getTaskDefinitionKey()) .setAnnotation("重新执行" ) .startBeforeActivity(curr.getTaskDefinitionKey()) .execute();
包括流程中产生的变量信息,包括控制流程流转的变量,网关、业务表单中填写的流程需要用到的变量等。很多地方都要用到
流程变量变量传递
变量最终会存在
act_ru_variable
这个表里面
在绘制流程图的时候,如果是用户任务(userService) 可以设置变量,比如执行人,
写法有这么几种方式
写死,就比如 zhangsan
ProcessInstance instance = runtimeService.startProcessInstanceByKey(key, new HashMap<>());
runtimeService.setVariable(instance.getId(), Constants.PATIENT_ID, relatedId);
Object variable = runtimeService.getVariable(instance.getId(), Constants.GENERAL_ID);
历史变量查询
HistoricVariableInstance variableInstance = historyService.createHistoricVariableInstanceQuery().processInstanceId(bo.getId().toString()). variableName(Constants.PATIENT_ID).singleResult();//变量值 variableInstance.getValue();//变量名称 variableInstance.getName();
针对后端来说任务类型主要有两种。
用户任务-userTask
即需要用户参与的任务,因为工作流执行过程中需要涉及到审批、过审之类的需要用户参与的任务,这个时候需要用户参与,然后调用接口完成任务。
服务任务-serviceTask
即自动执行的任务,比如用户提交后,系统自动存储、修改状态等自动完成的任务。
任务类型是关键,可根据配型配置实现调用 java的方法,spring 的bean方法,等等有这么几种类型
推荐使用 — Delegate Expression !!!
在系统任务中,因为是自动执行,所以实际应用中需要嵌入各种业务逻辑,可以在流程图设计中,按照下面方式调用java代码执行,在spring中配置同名的bean
配置表达式,可以实现
Java
Delegate接口使用类名配置,快捷写法如下,比较推荐下面这种,此种可灵活配置bean和spring结合使用,注入service等业务方法
@Bean ("t17" )JavaDelegate t17 () { return execution -> { Map<String, Object> variables = execution.getVariables(); Task task = taskService.createTaskQuery().processInstanceId(execution.getProcessInstanceId()).singleResult(); //业务逻辑 task.setOwner(String.valueOf(dentistId)); }; }
Java Class :
配置java类名,需要实现JavaDelegate接口,注意是全路径名,不可以使用
Spring
的bean配置!!!
@Component public class T17Delegate implements JavaDelegate { @Override public void execute (DelegateExecution execution) throws Exception { String taskId = execution.getId(); String instanceId = execution.getProcessInstanceId(); Map<String, Object> variables = execution.getVariables(); } }
下面两种可使用spring的配置
Expression:
EL表达式,调用java类的方法 ,规范:
expression=“#{monitorExecution.execution(execution)}”
@Component ("monitorExecution" )public class MonitorExecution { public void execution (DelegateExecution execution) { String processInstanceId = execution.getProcessInstanceId(); } }
任务监听器 – Task Listener
任务监听器用于在某个与任务相关的事件发生时执行自定义Java逻辑或表达式。它只能作为用户任务的子元素添加到流程定义中。
请注意,这也必须作为BPMN 2.0扩展元素的子级和Camunda命名空间中发生,因为任务侦听器是专门为Camunda引擎构建的。
适用场景:
@Bean TaskListener t21 () { return delegateTask -> { String taskId = delegateTask.getId(); String instanceId = delegateTask.getProcessInstanceId(); Map<String, Object> variables = delegateTask.getVariables(); // TODO: 20log/3/22 delegateTask.setVariable("" , "" ); }; }
执行监听器 – Execution Listener
执行侦听器在流程执行过程中发生某些事件时执行外部Java代码或计算表达式。可以用在任何任务中,可以捕获的事件有:
适用场景:每个任务结束时设置任务进度
public class ExampleExecutionListenerOne implements ExecutionListener { public void notify (DelegateExecution execution) throws Exception { execution.setVariable("variableSetInExecutionListener" , "firstValue" ); execution.setVariable("eventReceived" , execution.getEventName()); } }
扩展属性- Extension properties
扩展属性适用于很多自定义的业务属性,比如设置业务流程进度
流程权限及创建人设置
IdentityService为鉴权相关服务,但是我们实际开发中,一般会用到我们自己的鉴权系统,所以可以使用camunda提供的api来设置,具体可以看IdentityServiceImpl这个类,其中也是使用了ThreadLocal来保存鉴权信息 ,代码在下面
private ThreadLocal<Authentication> currentAuthentication = new ThreadLocal<Authentication>();
用户信息设置:
// Userutil是我们自己封装的用户工具类 identityService.setAuthenticatedUserId(UserUtil.getUserId().toString()); //获取 Authentication authentication = identityService.getCurrentAuthentication();
他内置很多比如开启流程时候,会默认找当前登录的人,这个类
DefaultHistoryEventProducer
// set super process instance id ExecutionEntity superExecution = executionEntity.getSuperExecution(); if (superExecution != null ) { evt.setSuperProcessInstanceId(superExecution.getProcessInstanceId()); } //state evt.setState(HistoricProcessInstance.STATE_ACTIVE); // set start user Id evt.setStartUserId(Context.getCommandContext().getAuthenticatedUserId());
任务执行人及发起人设置
//根据任务id设置执行人 taskService.setAssignee(task.getId(), UserUtil.getUserId().toString());
来源:blog.csdn.net/yu619251940/
article/details/129670382
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/147627.html
赞
(0)
01系统清理工具 去年腾讯开源了一个系统清理工具:腾讯柠檬清理,该软件可以系统性解决 macOS 设备空间问题。 重点聚焦清理功能,对上百款软件提供定制化的清理方案,提供专业的清理…
2023年5月5日
0
1
3
一、前言 上一讲我们讲到了 Eureka 注册中心的 Server 端有三级缓存来保存注册信息,可以利用缓存的快速读取来提高系统性能。我们再来细看下: 一级缓存:只读缓存 read…
2023年5月24日
0
0
0
点击关注公众号,实用技术文章及时了解 概念 工作流。通过计算机对业务流程自动化执行管理,主要解决的是“使在多个参与者之间按照某种预定义的规则自动进行传递文档、信息或任务的过程,从而…
2022年11月11日
0
0
8
点击关注公众号,实用技术文章及时了解 设定一个场景,假如一个商品接口在某段时间突然上升,会怎么办? 生活中的例子来说,假设冰墩墩在当天晚上上热搜之后,迅速有十几万人去淘宝下单购买,…
2022年11月21日
0
3
0
IntelliJ idea 近期连续发布多个EAP版本,官方在对用户体验不断优化的同时,也新增了一些不错的功能,尤其是人工智能助手补充,AI Assistant,相信在后续IDEA…
2023年7月12日
0
0
2
「什么是责任链」 责任链模式(Chain of Responsibility Pattern):责任链模式是⼀种对象的⾏为模式。 我们可以简单地理解为:当一个请求从执行开始到结束,…
2023年1月28日
0
0
0
介绍 WebSocket大家应该是再熟悉不过了,如果是单体应用确实不会有什么问题,但是当我们的项目使用微服务架构时,就可能会存在问题 比如服务A有两个实例A1和A2,前端的WebS…
2023年4月4日
0
0
3
DragonflyDB 是一个现代化的开源内存数据库,兼容 Redis 和 Memcached API,迁移时无需修改任何代码,可作为两者的替代方案。 与传统的内存数据存储相比,D…
2023年4月6日
0
0
4
文章目录 介绍ChatGPT ChatGPT示例 试用ChatGPT ChatGPT原理 ChatGPT应用 5.1 世界杯问题咨询 5.2 写书信(情书) 总结 1. 介绍Cha…
2023年2月21日
0
0
9