当前位置: 首页 > news >正文

工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求

前言

大家好,我是老马。

最近想设计一款审批系统,于是了解一下关于流程引擎的知识。

下面是一些的流程引擎相关资料。

工作流引擎系列

工作流引擎-00-流程引擎概览

工作流引擎-01-Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求

工作流引擎-02-BPM OA ERP 区别和联系

工作流引擎-03-聊一聊流程引擎

工作流引擎-04-流程引擎 activiti 优秀开源项目

工作流引擎-05-流程引擎 Camunda 8 协调跨人、系统和设备的复杂业务流程

工作流引擎-06-流程引擎 Flowable、Activiti 与 Camunda 全维度对比分析

工作流引擎-07-流程引擎 flowable-engine 入门介绍

工作流引擎-08-流程引擎 flowable-engine 优秀开源项目

工作流引擎-09-XState 是一个 JavaScript 和 TypeScript 的状态管理库,它使用状态机和状态图来建模逻辑

Activiti 基础介绍

主页:http://activiti.org

是什么

在解释activiti之前我们看一下什么是工作流。

workflow-工作流

工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。

我的理解是,工作流将一套大的业务逻辑分解成业务逻辑段, 并统一控制这些业务逻辑段的执行条件,执行顺序以及相互通信。

实现业务逻辑的分解和解耦。

Activiti

Activiti 是领先的轻量级、以 Java 为中心的开源 BPMN 引擎,支持现实世界的流程自动化需求。

Activiti Cloud 现在是新一代的业务自动化平台,提供一组旨在在分布式基础架构上运行的云原生构建块。

BPMN即业务流程建模与标注(Business Process Model and Notation,BPMN) ,描述流程的基本符号,包括这些图元如何组合成一个业务流程图(Business Process Diagram)。

快速开始

开始方式

可以基于云,也可以基于 java api 进行实现。

我们这里进行 java 的入门学习,java core api。

Activiti Core Runtime API 入门

创建新 API 的目的很明确,旨在满足以下要求:

  • 为我们的云方法提供清晰的路径

  • 隔离内部和外部 API 以提供向前的向后兼容性

  • 通过遵循单一职责方法提供模块化的未来路径

  • 减少旧版本 API 的混乱

  • 将安全和身份管理作为一等公民

  • 减少常见用例的价值实现时间,在这些用例中您希望依赖流行框架提供的约定

  • 提供底层服务的替代实现

  • 使社区能够在尊重既定合同的同时进行创新

我们尚未弃用旧 API,因此您仍然可以自由使用它,但我们强烈建议使用新 API 以获得长期支持。

此 API 处于测试阶段,这意味着我们可能会在 GA 发布之前对其进行更改和完善。我们将感谢我们从社区用户那里获得的所有反馈,如果您想参与该项目,请与我们联系。

是时候让我们接触几个示例项目了。

任务运行时 API

如果您正在构建业务应用程序,为您组织中的用户和组创建任务可能会很方便。

TaskRuntime API 可以帮助您。

你可以从 GitHub 克隆这个例子:https://github.com/Activiti/activiti-examples

本节的代码可以在 activiti-api-basic-task-example maven 模块中找到。

如果您在 Spring Boot 2 应用程序中运行,您只需要添加 activiti-spring-boot-starter 依赖项和一个 DB 驱动程序,您可以使用 H2 进行内存存储。

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/pom.xml#L45

maven 引入

<dependency><groupId>org.activiti</groupId><artifactId>activiti-spring-boot-starter</artifactId>
</dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId>
</dependency>

我们建议使用我们的 BOM

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/pom.xml#L30

<dependencyManagement><dependencies><dependency><groupId>org.activiti.dependencies</groupId><artifactId>activiti-dependencies</artifactId><version>7.1.0.M5</version><scope>import</scope><type>pom</type></dependency></dependencies>
</dependencyManagement>

现在让我们切换到我们的 DemoApplication.class:

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L25

TaskRuntime

然后你就可以使用 TaskRuntime:

@Autowired
private TaskRuntime taskRuntime;

例如,您可以通过执行以下操作来创建任务:

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplication.java#L45

taskRuntime.create(TaskPayloadBuilder.create().withName("First Team Task").withDescription("This is something really important").withGroup("activitiTeam").withPriority(10).build());

此任务仅对属于 activitiTeam 的用户和所有者(当前登录的用户)可见。

您可能已经注意到,您可以使用 TaskPayloadBuilder 以流畅的方式参数化将要发送到 TaskRuntime 的信息。

为了处理安全性、角色和组,我们依赖 Spring Security 模块。

因为我们在 Spring Boot 应用程序中,所以我们可以使用 UserDetailsService 来配置可用用户及其各自的组和角色。

我们目前正在 @Configuration 类中执行此操作:

https://github.com/Activiti/activiti-examples/blob/master/activiti-api-basic-task-example/src/main/java/org/activiti/examples/DemoApplicationConfiguration.java#L26

这里需要注意的重要一点是,为了作为用户与 TaskRuntime API 交互,您需要具有角色:ACTIVITI_USER (Granted Authority: ROLE_ACTIVITI_USER) 。

在与 REST 端点交互时,授权机制将设置当前登录的用户,但为了示例,我们使用了一个实用程序类(SecurityUtil.java#L26) 允许我们在上下文中设置手动选择的用户。

请注意,除非您正在尝试并且想在不通过 REST 端点的情况下更改用户,否则您永远不应该这样做。

查看“网络”示例以查看更多根本不需要此实用程序类的真实场景。

示例中要强调的最后一件事是任务事件侦听器的注册:

DemoApplication.java#L89

@Bean
public TaskRuntimeEventListener taskAssignedListener() {return taskAssigned-> logger.info(">>> Task Assigned: '"+ taskAssigned.getEntity().getName()+"' We can send a notification to the assignee: "+ taskAssigned.getEntity().getAssignee());
}

您可以根据需要注册任意数量的 TaskRuntimeEventListener。

这将使您的应用程序能够在服务触发运行时事件时收到通知。

进程运行时 API

以类似的方式,如果您想开始使用 ProcessRuntime API,您需要包含与以前相同的依赖项。

我们的目标是在未来提供更多的灵活性和独立的运行时,但现在同一个 Spring Boot Starter 提供 TaskRuntime 和 ProcessRuntime API。

本节的代码可以在“activiti-api-basic-process-example”maven 模块中找到。

接口

public interface ProcessRuntime {ProcessRuntimeConfiguration configuration();ProcessDefinition processDefinition(String processDefinitionId);Page processDefinitions(Pageable pageable);Page processDefinitions(Pageable pageable,GetProcessDefinitionsPayload payload);ProcessInstance start(StartProcessPayload payload);Page processInstances(Pageable pageable);Page processInstances(Pageable pageable,GetProcessInstancesPayload payload);ProcessInstance processInstance(String processInstanceId);ProcessInstance suspend(SuspendProcessPayload payload);ProcessInstance resume(ResumeProcessPayload payload);ProcessInstance delete(DeleteProcessPayload payload);void signal(SignalPayload payload);...
}

与 TaskRuntime API 类似,为了与 ProcessRuntime API 交互,当前登录的用户需要具有“ACTIVITI_USER”角色。

自动装配

首先,让我们自动装配我们的 ProcessRuntime:

DemoApplication.java#L32

@Autowired
private ProcessRuntime processRuntime;@Autowired
private SecurityUtil securityUtil;

和以前一样,我们需要我们的 SecurityUtil 助手来定义我们正在与我们的 API 交互的用户。

现在我们可以开始与 ProcessRuntime 交互:

DemoApplication.java#L47

Page processDefinitionPage = processRuntime.processDefinitions(Pageable.of(0, 10));
logger.info("> Available Process definitions: " +processDefinitionPage.getTotalItems());
for (ProcessDefinition pd : processDefinitionPage.getContent()) {logger.info("\t > Process definition: " + pd);
}

流程定义需要放在 /src/main/resources/processes/ 中。

对于本示例,我们定义了以下流程:

我们正在使用 Spring 调度功能每秒启动一个进程,从数组中获取随机值以进行处理:

DemoApplication.java#L67

@Scheduled(initialDelay = 1000, fixedDelay = 1000)
public void processText() {securityUtil.logInAs("system");String content = pickRandomString();SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yy HH:mm:ss");logger.info("> Processing content: " + content+ " at " + formatter.format(new Date()));ProcessInstance processInstance = processRuntime.start(ProcessPayloadBuilder.start().withProcessDefinitionKey("categorizeProcess").withProcessInstanceName("Processing Content: " + content).withVariable("content", content).build());logger.info(">>> Created Process Instance: " + processInstance);
}

和以前一样,我们使用 ProcessPayloadBuilder 以流畅的方式参数化我们想要启动哪个流程以及使用哪些流程变量。

现在,如果我们回顾流程定义,您会发现 3 个服务任务。

为了提供这些服务任务的实现,您需要定义连接器:

DemoApplication.java#L81

@Bean
public Connector processTextConnector() {return integrationContext -> {Map inBoundVariables = integrationContext.getInBoundVariables();String contentToProcess = (String) inBoundVariables.get("content")// Logic Here to decide if content is approved or notif (contentToProcess.contains("activiti")) {logger.info("> Approving content: " + contentToProcess);integrationContext.addOutBoundVariable("approved",true);} else {logger.info("> Discarding content: " + contentToProcess);integrationContext.addOutBoundVariable("approved",false);}return integrationContext;};
}

这些连接器使用 Bean 名称自动连接到 ProcessRuntime,在本例中为“processTextConnector”。

这个 bean 名称是从我们流程定义中的 serviceTask 元素的 implementation 属性中提取的:

categorize-content.bpmn20.xml#L22

<bpmn:serviceTask id="Task_1ylvdew" name="Process Content" implementation="processTextConnector">

这个新的连接器接口是 JavaDelegates 的自然演变,新版本的 Activiti Core 将尝试通过将它们包装在连接器实现中来重用你的 JavaDelegates:

public interface Connector {IntegrationContext execute(IntegrationContext integrationContext);
}

连接器接收带有流程变量的 IntegrationContext 并返回修改后的 IntegrationContext 以及需要映射回流程变量的结果。

在前面的示例中,连接器实现正在接收“内容”变量并根据内容处理逻辑添加“已批准”变量。

在这些连接器中,您可能会包含系统到系统调用,例如 REST 调用和基于消息的交互。 这些交互往往变得越来越复杂,因此我们将在未来的教程中看到如何从 ProcessRuntime(云连接器)上下文之外运行中提取这些连接器,以解耦此类外部交互的责任。 ProcessRuntime 范围。

检查 maven 模块 activiti-api-spring-integration-example 以获得更高级的示例,使用 Spring Integrations 基于文件轮询器启动进程。

相关文章:

  • spark-shuffle 类型及其对比
  • Spring AI实现一个简单的问答系统
  • Java程序员从0学AI(二)
  • C# 使用 OpenCV 基础
  • spark调度系统核心组件SparkContext、DAGSchedul、TaskScheduler介绍
  • 【Fifty Project - D29】
  • 容器环境渗透测试工具(docker渗透测试工具、kubernetes)
  • 在CuPy中使用多节点多GPU环境
  • 2025年医美行业报告60+份汇总解读 | 附 PDF 下载
  • Golang的代码注释规范与实践
  • 【笔试强训day37】
  • 从 0 到 1 选对 AI 自动化平台,深度对比三大AI自动化平台:n8n vs Dify vs Coze(附选型指南与实战案例)
  • 简易的Java制作的c4爆炸倒计时程序
  • 时源芯微|接口滤波与防护电路的设计
  • 【课堂笔记】核方法和Mercer定理
  • 打造高效数据处理利器:用Python实现Excel文件智能合并工具
  • Java EE进阶1:导读
  • 科技赋能·长效治理|无忧树建筑修缮渗漏水长效治理交流会圆满举行!
  • Spring Boot 使用 jasypt配置明文密码加密
  • Canvas SVG BpmnJS编辑器中Canvas与SVG职能详解
  • 广西隆林发生一起山洪灾害,致4人遇难
  • 66岁华仁世纪集团有限公司创始人、董事长梁福东逝世
  • 外交部:巴基斯坦副总理兼外长达尔5月19日至21日访华
  • 央媒:设施老化、应急预案套模板,养老机构消防隐患亟待排查
  • 梅花奖在上海|秦海璐:演了15年《四世同堂》,想演一辈子
  • 李洋谈美国黑帮电影与黑帮文化