相关文章推荐
气势凌人的跑步鞋  ·  Invoke-Sqlcmd ...·  2 周前    · 
一身肌肉的砖头  ·  看视频截图-掘金·  1 年前    · 
强健的日记本  ·  Cannot load driver ...·  1 年前    · 
个性的拐杖  ·  arrch64 ...·  1 年前    · 
沉着的脸盆  ·  C# 入门(14) ...·  1 年前    · 

前言:因为公司有个项目需求要使用到工作流引擎,考查了市面各种的工作流引擎,对比它们之间的优劣势,最后选择Camunda工作流引擎。此前自己对Camunda工作流引擎了解的并不多,所以就记录下自己学习Camunda工作流引擎到springboot项目中整合Camunda工作流引擎使用的过程。

在上一篇文章中已经介绍了Camunda Platform和Modeler创建工作流的玩法了。在本文就将Camunda 应用在生产项目的各种审核流程中,重点是springboot整合Camunda ,并使用Camunda 的各种API。因为camunda本来就是一个轻量级的框架,项目中就主要使用Camunda 的工作流的流程流转和审核,流程的创建和前端bpmn页面流程编辑器部分这里就不介绍使用了。因为在经历几个生产项目,无论是使用flowable或者Camunda 工作流框架,流程bpmn文件都是提前通过其他工具创建好,然后放在项目中加载部署的,项目主要是对应的流程的流转和审核。不多废话,下面就直接进入正题。

一、引入Camunda依赖

springboot引入Camunda要考虑版本兼容性的问题,我的springboot版本2.5.x,所以我引入Camunda的版本是7.16.x,

要看springboot对应Camunda的具体的版本:

https://docs.camunda.org/manual/7.19/user-guide/spring-boot-integration/version-compatibility/

<dependency>
    <groupId>org.camunda.bpm.springboot</groupId>
    <artifactId>camunda-bpm-spring-boot-starter</artifactId>
    <version>7.16.0</version>
</dependency>
二、在yml配置camunda

camunda的详细配置说明:

https://docs.camunda.org/manual/latest/user-guide/spring-boot-integration/configuration/#camunda-engine-properties

这里就说几个比较重要的配置

camunda.bpm.auto-deployment-enabled :流程是否应该自动部署,默认为true。

很重要camunda.bpm.deployment-resource-pattern:自动部署位置。一开始我学习我不理解为什么bpmn文件无论放在那里都能自动部署。

默认位置:

classpath*😗*/*.bpmn,

classpath*😗*/*.bpmn20.xml,

classpath*😗*/*.dmn,

classpath*😗*/*.dmn11.xml,

classpath*😗*/*.cmmn,

classpath*😗*/*.cmmn10.xml,

classpath*😗*/*.cmmn11.xml

camunda.bpm.database.schema-update: 如果应应用自动架构更新,请使用 [true、false、create、create-drop、drop-create] 之一,默认为true。

camunda.bpm.database.type: 底层数据库的类型。可能的值:h2、mysql、mariadb、oracle、postgres、mssql、db2。

camunda.bpm.admin-user.id: 用户名

camunda.bpm.admin-user.password: 初始化密码

camunda.bpm.admin-user.firstName: 附加(可选)用户属性 ,默认为“id”的值

camunda.bpm.admin-user.lastName: 附加(可选)用户属性 ,默认为“id”的值

camunda.bpm.filter.create:“显示全部”过滤器的名称。如果设置,则会在启动时创建一个显示所有任务的新过滤器。

下面是在实际项目中的配置

# camunda配置
camunda:
  bpm:
    admin-user:
      id: camunda
      password: camunda
      first-name: admin
    filter:
      create: All tasks
    database:
      type: mysql
      schema-update: true
    auto-deployment-enabled: true
    deployment-resource-pattern: classpath:/processes/*.bpmn
三、初始化camunda数据库,执行建表脚本(很重要

这里需要手动建好camunda相关的表,不提前建好的话,到导致项目中的camunda的相关的bean没办法自动注入到spring容器中,会无法正常启动项目。camunda的相关脚本语句,去官网找到对应版本(此例中Camunda版本为7.16.0)的sql脚本文件:

https://camunda.com/download/

解压后,找到./configuration/sql目录下即可找到sql文件,engine和identity都执行。项目中使用的是mysql数据,所以执行mysql的脚本。

四、camunda数据库表的说明(扩展)

PS: 这一步跟项目无关,但是能加深对camunda的理解,而且对项目中出现问题的排查能提供很好的帮助。

Camunda bpm流程引擎的数据库由多个表组成,表名都以ACT开头,第二部分是说明表用途的两字符标识。而Camunda7.16版本共49张表。

ACT_RE_* : 'RE’表示流程资源存储,这个前缀的表包含了流程定义和流程静态资源(图片,规则等)
(最重要)ACT_RU_* : 'RU’表示流程运行时。 这些运行时的表,包含流程实例,任务,变量,Job等运行中的数据。 Camunda只在流程实例执行过程中保存这些数据,在流程结束时就会删除这些记录, 这样运行时表的数据量最小,可以最快运行
ACT_ID_* : 'ID’表示组织用户信息,比如用户,组等,
ACT_HI_* : 'HI’表示流程历史记录。 这些表包含历史数据,比如历史流程实例,变量,任务等
ACT_GE_* : ‘GE’表示流程通用数据

要记住一个很重要的一个点:流程运行时的数据是存在ACT_RU相关的表上,当流程结束后,该流程相关的数据就会被物理删除掉,能减少很多数据量,提高流程的性能。而想要看相关流程的过程记录,则需要到ACT_HI相关的表上去查找

流程引擎的最核心表是流程定义、流程执行、流程任务、流程变量和事件订阅表。它们之间的关系见下面的UML模型。

下面是项目中排查问题用的比较多,比较重要的几张表的说明

act_id_user(用户表)
字段名称字段类型可否为空描述
ID_varchar(64)主键
REV_int(11)NULL版本
FIRST_varchar(255)NULL
LAST_varchar(255)NULL
EMAIL_varchar(255)NULL邮件
PWD_varchar(255)NULL密码
SALT_varchar(255)NULL盐值
LOCK_EXP_TIME_datetimeNULL锁定过期时间
ATTEMPTS_int(11)NULL尝试次数
PICTURE_ID_varchar(64)NULL图片ID
act_ge_bytearray(二进制数据表)
字段名称字段类型可否为空描述
ID_varchar(64)主键
REV_int(11)NULL版本
NAME_varchar(255)NULL名称
DEPLOYMENT_ID_varchar(64)NULL部署ID
BYTES_longblobNULL字节内容
GENERATED_tinyint(4)NULL是否系统生成(0用户创建,null系统生成)
TENANT_ID_varchar(64)NULL租户ID
TYPE_int(11)NULL类型
CREATE_TIME_datetimeNULL创建时间
ROOT_PROC_INST_ID_varchar(64)NULL流程实例根ID
REMOVAL_TIME_datetimeNULL删除时间
act_re_procdef(流程定义表)

流程定义表,包含所有已部署的流程定义,诸如版本详细信息、资源名称或挂起状态等信息。

字段名称字段类型可否为空描述
ID_varchar(64)主键
REV_int(11)NULL版本
CATEGORY_varchar(255)NULL流程定义的Namespace分类
NAME_varchar(255)NULL流程定义名称
KEY_varchar(255)流程定义KEY
VERSION_int(11)流程定义版本号
DEPLOYMENT_ID_varchar(64)NULL部署ID
RESOURCE_NAME_varchar(4000)NULL资源名称
DGRM_RESOURCE_NAME_varchar(4000)NULLDGRM资源名称
HAS_START_FORM_KEY_tinyint(4)NULL是否有启动表单
SUSPENSION_STATE_int(11)NULL流程挂起
TENANT_ID_varchar(64)NULL租户ID
VERSION_TAG_varchar(64)NULL版本标签
HISTORY_TTL_int(11)NULL
STARTABLE_tinyint(1)是否是可启动流程
act_ru_execution(流程运行时表)—最重要

BPMN流程运行时记录表。该表时整个流程引擎的核心表,它包括流程定义、父级执行、当前活动和有关执行状态的不同元数据等信息。

字段名称字段类型可否为空描述
ID_varchar(64)主键
REV_int(11)NULL版本
ROOT_PROC_INST_ID_varchar(64)NULL流程实例根ID
PROC_INST_ID_varchar(64)NULL流程实例ID
BUSINESS_KEY_varchar(255)NULL业务KEY
PARENT_ID_varchar(64)NULL流程父实例ID
PROC_DEF_ID_varchar(64)NULL流程定义ID
SUPER_EXEC_varchar(64)NULL父流程实例对应的执行
SUPER_CASE_EXEC_varchar(64)NULL父案例实例对应的执行
CASE_INST_ID_varchar(64)NULL案例实例ID
ACT_ID_varchar(255)NULL节点ID
ACT_INST_ID_varchar(64)NULL节点实例ID
IS_ACTIVE_tinyint(4)NULL是否激活
IS_CONCURRENT_tinyint(4)NULL是否并行
IS_SCOPE_tinyint(4)NULL是否多实例范围
IS_EVENT_SCOPE_tinyint(4)NULL是否事件多实例范围
SUSPENSION_STATE_int(11)NULL挂起状态
CACHED_ENT_STATE_int(11)NULL缓存状态
SEQUENCE_COUNTER_bigint(20)NULL序列计数器
TENANT_ID_varchar(64)NULL租户ID
act_ru_identitylink(流程运行时表)

运行时流程人员表,主要存储当前节点参与者的信息

字段名称字段类型可否为空描述
ID_varchar(64)主键
REV_int(11)NULL版本
GROUP_ID_varchar(255)NULL用户组ID
TYPE_varchar(255)NULL类型
USER_ID_varchar(255)NULL用户ID
TASK_ID_varchar(64)NULL任务ID
PROC_DEF_ID_varchar(64)NULL流程定义ID
TENANT_ID_varchar(64)NULL租户ID
act_ru_task( 流程运行时任务表)

流程运行时任务表,包含所有正在运行的流程实例的所有打开的任务,包括诸如相应的流程实例、执行以及元数据(如创建时间、办理人或到期时间)等信息。

字段名称字段类型可否为空描述
ID_varchar(64)主键
REV_int(11)NULL版本
EXECUTION_ID_varchar(64)NULL流程执行ID
PROC_INST_ID_varchar(64)NULL流程实例ID
PROC_DEF_ID_varchar(64)NULL流程定义ID
CASE_EXECUTION_ID_varchar(64)NULL案例执行ID
CASE_INST_ID_varchar(64)NULL案例实例ID
CASE_DEF_ID_varchar(64)NULL案例定义ID
NAME_varchar(255)NULL名称
PARENT_TASK_ID_varchar(64)NULL父任务ID
DESCRIPTION_varchar(4000)NULL描述
TASK_DEF_KEY_varchar(255)NULL任务定义KEY
OWNER_varchar(255)NULL委托人
ASSIGNEE_varchar(255)NULL办理人
DELEGATION_varchar(64)NULL委托状态
PRIORITY_int(11)NULL优先级
CREATE_TIME_datetimeNULL创建时间
DUE_DATE_datetimeNULL截止时间
FOLLOW_UP_DATE_datetimeNULL跟踪时间
SUSPENSION_STATE_int(11)NULL挂起状态
TENANT_ID_varchar(64)NULL租户ID
act_hi_comment(历史流程审批意见表)

历史流程审批意见表,存放历史流程的审批意见。

字段名称字段类型可否为空描述
ID_varchar(64)主键
TYPE_varchar(255)NULL类型(event事件、comment意见)
TIME_datetime时间
USER_ID_varchar(255)NULL处理人
TASK_ID_varchar(64)NULL任务ID
ROOT_PROC_INST_ID_varchar(64)NULL流程实例跟ID
PROC_INST_ID_varchar(64)NULL流程实例ID
ACTION_varchar(255)NULL行为类型
MESSAGE_varchar(4000)NULL基本内容
FULL_MSG_longblobNULL全部内容
TENANT_ID_varchar(64)NULL租户ID
REMOVAL_TIME_datetimeNULL移除时间
act_hi_detail(历史的流程运行详情表)

历史的流程运行变量详情记录表。流程中产生的变量详细,包括控制流程流转的变量,业务表单中填写的流程需要用到的变量等。

字段名称字段类型可否为空描述
ID_varchar(64)主键
TYPE_varchar(255)类型
PROC_DEF_KEY_varchar(255)NULL流程定义KEY
PROC_DEF_ID_varchar(64)NULL流程定义ID
ROOT_PROC_INST_ID_varchar(64)NULL流程实例根ID
PROC_INST_ID_varchar(64)NULL流程实例ID
EXECUTION_ID_varchar(64)NULL流程执行ID
CASE_DEF_KEY_varchar(255)NULL案例定义KEY
CASE_DEF_ID_varchar(64)NULL案例定义ID
CASE_INST_ID_varchar(64)NULL案例实例ID
CASE_EXECUTION_ID_varchar(64)NULL案例执行ID
TASK_ID_varchar(64)NULL任务ID
ACT_INST_ID_varchar(64)NULL节点实例ID
VAR_INST_ID_varchar(64)NULL流程变量记录ID
NAME_varchar(255)名称
VAR_TYPE_varchar(255)NULL变量类型
REV_int(11)NULL版本
TIME_datetime时间戳
BYTEARRAY_ID_varchar(64)NULL二进制数据对应ID
DOUBLE_doubleNULLdouble类型值
LONG_bigint(20)NULLlong类型值
TEXT_varchar(4000)NULL文本类型值
TEXT2_varchar(4000)NULL文本类型值2
SEQUENCE_COUNTER_bigint(20)NULL序列计数器
TENANT_ID_varchar(64)NULL租户ID
OPERATION_ID_varchar(64)NULL
REMOVAL_TIME_datetimeNULL移除时间

五、编写camunda的工具类。

其实完成前面3步,可以说springboot已经整合camunda成功了,但是一个项目中引入一个框架主要是为了使用,camunda官方提供了很多API,参考官方文档:https://docs.camunda.org/manual/7.18/reference/rest/

但是在camunda不同的流程的审核所 使用的API是大多数是相同的,所以在项目中封装一个工具类提供使用。

* camunda 流程工具类 @Component @Slf4j public class FlowUtil { private static final FlowUtil util = new FlowUtil(); @Autowired private RepositoryService repositoryService; @Autowired private RuntimeService runtimeService; @Autowired private TaskService taskService; @Autowired private HistoryService historyService; @PostConstruct public void initialize() { util.repositoryService = repositoryService; util.runtimeService = runtimeService; util.taskService = taskService; util.historyService = historyService; * 部署流程,参数本地bpmn的路径 * @param filePath bpmn路径 * @param name 流程名称 public static void deployment(String filePath,String name){ log.info("开始部署本地审批流程:{},文件地址:{}",name,filePath); util.repositoryService.createDeployment() .name(name) .addClasspathResource(filePath) .deploy(); log.info("完成部署本地审批流程:{},文件地址:{}",name,filePath); * 启动流程 * @param key 流程标识,需唯一,如果存在相同key则会启动版本号最新的流程 * @param businessKey 业务id * @param map 流程变量(包含节点审批人及业务判断变量等) public static void startProcess(String key, Object businessKey, Map<String,Object> map){ log.info("开始启动审批流程:{},业务源:{},流程变量: {}",key,businessKey.toString(), JSONUtil.toJsonStr(JSONUtil.parse(map))); ProcessInstance processInstance = util.runtimeService.startProcessInstanceByKey(key, businessKey.toString(), map); log.info("完成启动审批流程:{},业务源:{},流程实例ID:{}",key,businessKey.toString(), processInstance.getId()); * 销毁流程 * @param key 流程标识,需唯一,如果存在相同key则会启动版本号最新的流程 * @param businessKey 业务id * @param reason 销毁原因 * @param reason 审批人 public static void destroyProcess(String key, String businessKey, String reason,String assignee){ //查询待办任务 List<Task> tasks = FlowUtil.getTaskByCandidateUserAndBusinessKey(key, businessKey, assignee); if(CollUtil.isEmpty(tasks)){ log.info("{}完成审批任务失败:{}--{}",assignee,key,businessKey); throw new ResultException("暂未到您审批"); FlowUtil.claimTask(tasks.get(0).getId(),assignee); List<Task> taskList = FlowUtil.getTasksByBusinessKey(key, businessKey); if(CollUtil.isEmpty(taskList)) return; log.info("开始销毁审批流程:{},业务源:{},流程实例ID:{}:",key,businessKey, taskList.get(0).getProcessInstanceId()); util.runtimeService.deleteProcessInstance(taskList.get(0).getProcessInstanceId(), reason); log.info("完成销毁审批流程:{},业务源:{},流程实例ID:{}",key,businessKey, taskList.get(0).getProcessInstanceId()); * 领取任务 * @param taskId 任务id * @param candidateUser 候选用户名 public static void claimTask(String taskId,String candidateUser){ Task task = util.taskService.createTaskQuery() .taskId(taskId) .taskCandidateUser(candidateUser) .singleResult(); if(Objects.isNull(task)){ log.info("{}领取审批任务失败:{}",candidateUser,taskId); throw new ResultException("任务领取失败"); util.taskService.claim(taskId,candidateUser); * 完成任务 * @param taskId 任务id * @param assignee 用户名 public static void completeTask(String taskId,String assignee){ Task task = util.taskService.createTaskQuery() .taskId(taskId) .taskAssignee(assignee) .singleResult(); if(Objects.isNull(task)){ log.info("{}完成审批任务失败:{}",assignee,taskId); throw new ResultException("任务完成失败"); util.taskService.complete(taskId); * 领取并完成任务 * @param taskId 任务id * @param assignee 用户名 public static void claimAndCompleteTask(String taskId,String assignee){ Task task = util.taskService.createTaskQuery() .taskId(taskId) .singleResult(); if(Objects.isNull(task)){ log.info("{}审批任务不存在:{}",assignee,taskId); throw new ResultException("审批任务不存在"); if(StrUtil.isNotBlank(task.getAssignee())){ if(!task.getAssignee().equalsIgnoreCase(assignee)){ log.info("{}完成审批任务失败:{}",assignee,taskId); throw new ResultException("暂未到您审批"); util.taskService.complete(taskId); return; Task unClaimTask = util.taskService.createTaskQuery() .taskId(taskId) .taskCandidateUser(assignee) .singleResult(); if(Objects.isNull(unClaimTask)){ log.info("{}完成审批任务失败:{}",assignee,taskId); throw new ResultException("暂未到您审批"); util.taskService.claim(taskId,assignee); util.taskService.complete(taskId); * 查询待办任务,参数:候选用户、业务id * @param candidateUser 候选用户 * @param key 流程标识,需唯一,如果存在相同key则会启动版本号最新的流程 * @param businessKey 业务id * @return public static List<Task> getTaskByCandidateUserAndBusinessKey(String key,String businessKey,String candidateUser){ return util.taskService.createTaskQuery() .processInstanceBusinessKey(businessKey) .processDefinitionKey(key) .taskCandidateUser(candidateUser) .list(); * 查询待办任务,参数: 业务id * @param key 流程标识,需唯一,如果存在相同key则会启动版本号最新的流程 * @param businessKey 业务id * @return public static List<Task> getTasksByBusinessKey(String key, String businessKey){ return util.taskService.createTaskQuery() .processDefinitionKey(key) .processInstanceBusinessKey(businessKey) .list(); * 查询待办任务,参数: 业务id * @param key 流程标识,需唯一,如果存在相同key则会启动版本号最新的流程 * @param businessKey 业务id * @param assignee 用户名 * @return public static boolean claimAndCompleteTask(String key, String businessKey,String assignee){ //查询待办任务 List<Task> tasks = FlowUtil.getTaskByCandidateUserAndBusinessKey(key, businessKey, assignee); if(CollUtil.isEmpty(tasks)){ log.info("{}完成审批任务失败:{}--{}",assignee,key,businessKey); throw new ResultException("暂未到您审批"); for (Task task : tasks) { FlowUtil.claimAndCompleteTask(task.getId(),assignee); if(CollUtil.isEmpty(FlowUtil.getTasksByBusinessKey(key,businessKey))){ return true; }else{ return false; * 查询历史任务 * @param key * @param businessKey * @return public static List<HistoricTaskInstance> getHistoricTask(String processInstanceId,String key, String businessKey){ return util.historyService.createHistoricTaskInstanceQuery() .processInstanceBusinessKey(businessKey) .processInstanceId(processInstanceId) .processDefinitionKey(key) .list(); * 查询历史实例 * @param key * @param businessKey * @return public static HistoricProcessInstance getLastProcessInstance(String key, String businessKey){ return util.historyService.createHistoricProcessInstanceQuery() .processDefinitionKey(key) .processInstanceBusinessKey(businessKey) .orderByProcessInstanceStartTime() .desc().list().get(0); * 查询任务 * @param key * @param taskId * @return public static List<HistoricIdentityLinkLog> getHistoricIdentityLinkLog(String key, String taskId){ return util.historyService.createHistoricIdentityLinkLogQuery() .processDefinitionKey(key) .taskId(taskId) .list(); * 查询任务 * @param taskId * @return public static List<IdentityLink> getTaskIdentityLink(String taskId){ return util.taskService.getIdentityLinksForTask(taskId);
五、模拟生产项目中的功能-费用审核流程

下面是费用审核的流程图

5.1 创建费用审核流程(即创建bpmn文件)

创建流程可以使用Camunda Modeler,具体的使用方法在我上一篇文章中有写到,又不了解的可以移步到:

https://blog.csdn.net/qq798867485/article/details/131439688

下面是流程图的创建和每个节点的设置情况

5.2 把bpmn文件放到项目的processes目录

一定要放在这个目录下,因为之前的yml的配置指定了自动部署的目录,不然无法自动部署。除非你在yml配置中不制动自动部署的目录。

5.3 创建费用审核流程

FlowUtil.startProcess(BizFlowTypeEnum.EXPENSE_APPROVE.getKey(),expense.getId(),params);

这个方法就是 创建费用审核流程

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void submit(Expense expense) {
        dao.insert(expense);
        List<User> userList = userService.listAll(new UserQueryBo());
        Set<String> companyUsers = userList.stream().filter(x -> x.getUserRole() == 1)
                .map(item -> item.getId().toString()).collect(Collectors.toSet());
        Set<String> groupUsers = userList.stream().filter(x -> x.getUserRole() == 2)
                .map(item -> item.getId().toString()).collect(Collectors.toSet());
        Set<String> headUsers = userList.stream().filter(x -> x.getUserRole() == 3)
                .map(item -> item.getId().toString()).collect(Collectors.toSet());
        Map<String,Object> params = new HashMap<>();
        params.put("companyUsers", companyUsers);
        params.put("groupUsers",groupUsers);
        params.put("headUsers",headUsers);
        FlowUtil.startProcess(BizFlowTypeEnum.EXPENSE_APPROVE.getKey(),expense.getId(),params);
5.4 审核费用审核流程

##查看这个审核节点是否为审核流程最后的一个节点

FlowUtil.claimAndCompleteTask(BizFlowTypeEnum.EXPENSE_APPROVE.getKey(),expense.getId().toString(),expenseQueryBo.getApprovalId().toString())

FlowUtil.destroyProcess(BizFlowTypeEnum.EXPENSE_APPROVE.getKey(),expense.getId().toString(),“不想通过”,expenseQueryBo.getApprovalId().toString())

 @Override
    @Transactional(rollbackFor = Exception.class)
    public void approval(Expense expense, ExpenseQueryBo expenseQueryBo) {
        if(expenseQueryBo.getApprovalStatus() == 2){
            if(FlowUtil.claimAndCompleteTask(BizFlowTypeEnum.EXPENSE_APPROVE.getKey(),expense.getId().toString(),expenseQueryBo.getApprovalId().toString())){
                expense.setApprovalStatus(2);
            }else {
                expense.setApprovalStatus(1);
        }else {
            FlowUtil.destroyProcess(BizFlowTypeEnum.EXPENSE_APPROVE.getKey(),expense.getId().toString(),"不想通过",expenseQueryBo.getApprovalId().toString());
            expense.setApprovalStatus(3);
        this.updateById(expense);
六、总结(代码)

学习camunda最主要是理解流程的流转和相关表的结构。上面只是我简单模拟一个费用审核流程的样例,实际生产中的业务代码比这个要复杂,但是核心的camunda的工具类的使用是不变的,变的只是业务流程。

例子完整的代码:https://github.com/gorylee/learnDemo/tree/master/camundaDemo

Camunda工作流源自于activity5,是德国的一个工作流程自动化软件开发商提供的 目前提供了两个版本: Camunda7(组件化)和Camunda8(云原生平台) 1.2支持的模型 BPMN2 (Business Process Model And Notation) 业务流程模型标记 CMMN (Case Management Model And Notation) 案例管理模型标记 DMN (Decision Model
使用camunda开源工作流引擎有:通过docker运行、使用springboot集成、部署camunda发行包、基于源代码编译运行等多种方式。 其中,通过源代码编译运行的方式最为复杂,具体参考:https://lowcode.blog.csdn.net/article/details/136206057 文本重点介绍如何在Spring Boot应用程序中如何集成Camunda Platform开源流程平台,这也是项目中最为常见的一种使用方式。
如果您想添加 Camunda BPM Rest API,您必须将以下依赖项添加到您的 Maven 构建中。 < dependency> < groupId>org.camunda.bpm</ groupId> < artifactId>camunda-engine-rest</ artifactId> < classifier>classes</ classifier> < version>7.2.0</ version> </ dependency> 如果它存在于类路径中,它将被自动检测并在 . 以弹簧为例 <dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter</artifactId> <version>7.13.0&lt <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> <optional>true</optional> </depe <dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter</artifactId> <version>${camunda.spring.boot.version}</version> </dependency> 2. 在 application.properties 或 application.yml 文件中添加以下配置: ```yaml camunda.bpm: database: schema-update: true process-engine: name: default job-execution: enabled: true enabled: true 这里设置了数据库更新、默认流程引擎、任务执行和 DMN 支持等配置。 3. 在 Spring Boot 应用程序中创建 DMN 决策表,例如 resources 目录下的 my-decision.dmn 文件。 4. 在应用程序中通过以下代码进行 DMN 决策表的执行和结果输出: ```java import org.camunda.bpm.dmn.engine.DmnDecisionTableResult; import org.camunda.bpm.engine.DecisionService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class MyService { @Autowired private DecisionService decisionService; public void executeDecision() { DmnDecisionTableResult result = decisionService.evaluateDecisionTableByKey("my-decision").execute(); System.out.println(result.getSingleResult()); 这里使用Camunda DMN 决策服务中的 evaluateDecisionTableByKey 方法执行决策表并获取结果。 以上是一个简单的 Camunda DMN 集成 Spring Boot 的示例,你可以根据自己的需求和实际情况进行配置和调整。