大家好,欢迎来到IT知识分享网。
文章目录
一、camunda基础
Camunda介绍 Camunda是一种工作流引擎,是由Java开发的一个纯Java库。
通常集成在我们的服务中,作为其中一块功能。
1.1 安装与部署流程引擎
官方-下载引导地址
- Camunda Platform 和 Camunda Modeler是必要的文件。
- Camunda Platform:这里是流程引擎的用户、租户等部分的管理界面
- Camunda Modeler:流程引擎的核心,即流程相关的部分
- docker安装
docker pull camunda/camunda-bpm-platform:run-latest docker run -d --name camunda -p 8080:8080 camunda/camunda-bpm-platform:run-latest
- 非docker安装
Camunda Platform 下载地址
修改default.yml 中数据源和JDBC 替换为自己使用的数据库的配置
然后把对应的JDBC放入标注上面的userlib之中即可。
1.2 流程引擎结构
1.3 流程引擎的基本使用
我们创建在Camunda Modeler中创建一个流程,然后我们可以用Java或者JS,按照流程去执行它。
本篇使用Java处理。
1.3.1 创建一个BPMN Diagram
首先,我们可以创建一个BPMN Diagram。
Business Process Modeling Notation,简称BPMN
它的事件包含
- 开始(Start)
- 中间(Intermediate)
- 边界(Boundary)
- 结束(End)
根据触发方式不同,可以分为
- 捕获事件(Catching Event)
- 抛出事件(Throwing Event)
具体的使用方式请参考:参考-Executing automated steps、Service tasks
1.3.2 实现一个外部工作者
换言之就是创建一个Java程序,用它以处理BPMN Diagram
这里是官方的写的依赖,依据自己的需要改动即可。
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.camunda.bpm.getstarted</groupId> <artifactId>charge-card-worker</artifactId> <version>0.0.1-SNAPSHOT</version> <properties> <camunda.external-task-client.version>7.17.0</camunda.external-task-client.version> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.camunda.bpm</groupId> <artifactId>camunda-external-task-client</artifactId> <version>${camunda.external-task-client.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.6.1</version> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> <version>2.3.1</version> </dependency> </dependencies> </project>
笔者改为Spring Boot(Java11)
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.7.6</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>javax.xml.bind</groupId> <artifactId>jaxb-api</artifactId> </dependency> <dependency> <groupId>org.camunda.bpm</groupId> <artifactId>camunda-external-task-client</artifactId> <version>7.18.0</version> </dependency> </dependencies>
import lombok.extern.slf4j.Slf4j; import org.camunda.bpm.client.ExternalTaskClient; import java.awt.*; import java.net.URI; @Slf4j public class ChargeCardWorker {
public static void main(String[] args) {
ExternalTaskClient client = ExternalTaskClient.create() // 依据实际情况填写程序的IP和端口 .baseUrl("http://localhost:8080/engine-rest") // 异步相应超时时间 .asyncResponseTimeout(10000) // long polling timeout .build(); // subscribe to an external task topic as specified in the process // 订阅流程中指定的外部任务主题,与活动ID对应 client.subscribe("charge-card") // 默认锁的持续时间为20秒 .lockDuration(1000) // the default lock duration is 20 seconds, but you can override this // 处理内容 // externalTask:任务,externalTaskService:处理服务 .handler((externalTask, externalTaskService) -> {
// Put your business logic here // Get a process variable String item = externalTask.getVariable("item"); Integer amount = externalTask.getVariable("amount"); log.info("Charging credit card with an amount of '{}'€ for the item '{}'...",amount,item); try {
// 打开页面并挂起 Desktop.getDesktop().browse(new URI("https://docs.camunda.org/get-started/quick-start/complete")); } catch (Exception e) {
e.printStackTrace(); } // Complete the task // 任务完成 externalTaskService.complete(externalTask); }) .open(); } }
这里的活动的Topic与我们的工作者一致。因而可以知道活动有对应的工作者去处理。
通过改变活动以及活动的顺序来改变流程,而活动自己被不同的工作者处理后继续流转因而不受影响,以此完成流程。
1.3.3 部署流程
1.3.4 创建一个流程实例并消费
http://localhost:8080/engine-rest/process-definition/key/payment-retrieval/start
同时在body里面发送如下json参数
{
"variables": {
"amount": {
"value":555, "type":"integer" }, "item": {
"value": "item-xyz" } } }
此处的key就是我们process的ID:payment-retrieval
1.3.5 向流程中添加用户任务
当然这里只是最简单的使用。参考-Add a User Task to the Process
http://localhost:8080/camunda/app/tasklist/
选择我们创建的流程,开启一个流程
输入一个业务流程号后,我们可以找到我们的流程以及表格
同时可以看到流程位置
填写完成后,我们继续,则会流转到我们前面写的消费者处。
1.3.6 添加网关
也就是类似if-else的方式,来确定流向。
我们先搭出如下内容
网关1
- 如果金额小于 1000 就直接处理
- 如果大等于 1000 就需要处理
网关2
- 判断是否同意
接下来我们部署该流程,按照1.3.5中流程开始一个流程,或者通过PostMan请求,可以看到流程流转到了不同地方。
platform 创建流程
postman 创建流程
发送的也是和之前一样的请求
可以看到我们这里的流程到了1.3.5的部分,在tasklist中我们处理是否同意即可。
1.3.7 业务规则
创建如下内容
- 如果我们的item是”item-xyz”决策就是赞成
- 若果不是,则结果就是不赞成
关于决策表,可以参考Camunda DMN
在重新部署我们的流程
然后我们开始流程
二、Java 集成流程引擎
我们用SpringBoot集成流程引擎。
可以参考-Camunda-Spring Boot 集成
相关的SpringBoot配置可以参考-流程引擎配置
2.1 为项目引入Platform
<properties> <maven.compiler.source>11</maven.compiler.source> <maven.compiler.target>11</maven.compiler.target> <camunda.spring-boot.version>7.18.0</camunda.spring-boot.version> <spring-boot.version>2.7.3</spring-boot.version> <xml-bind.version>2.3.6</xml-bind.version> <maven.compiler.target>11</maven.compiler.target> <mybatis-plus.version>3.5.1</mybatis-plus.version> </properties> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter</artifactId> <version>${camunda.spring-boot.version}</version> </dependency> <dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId> <version>${camunda.spring-boot.version}</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter</artifactId> <version>${camunda.spring-boot.version}</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>${mybatis-plus.version}</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-extension</artifactId> <version>${mybatis-plus.version}</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies>
yml
server: port: 8080 spring: datasource: url: jdbc:mysql://IP:Port/DataBase?useUnicode=true&NamePatternMatchesAll=true&characterEncoding=UTF-8&allowPublicKeyRetrieval=true&useSSL=false username: username password: password driver-class-name: com.mysql.cj.jdbc.Driver application: name: applicationName camunda: bpm: admin-user: id: demo password: demo mybatis: configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true
package camunda; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class CamundaApplication {
public static void main(String[] args){
SpringApplication.run(CamundaApplication.class,args); } }
启动后我们访问
http://localhost:8080/camunda/app/welcome/default/#!/login
2.1.1 页面配置
有页面是因为我们引入了,不需要页面的时候,我们可以不引入它即可。
<dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter-webapp</artifactId> <version>${camunda.spring-boot.version}</version> </dependency>
此外,我们可以配置yml,来修改路径以及是否重定向到默认的index.html.
camunda: bpm: webapp: application-path: 路径 index-redirect-enabled: false
2.2 简单使用
可以参考-Camunda BPM Javadocs 7.9.19-ee
2.2.1 引入API
我们可以引入如下依赖:
<dependency> <groupId>org.camunda.bpm.springboot</groupId> <artifactId>camunda-bpm-spring-boot-starter-rest</artifactId> <version>${camunda.spring-boot.version}</version> </dependency>
关于是否需要这个扩展包,new bing 给出的答复如下:
Camunda BPM Spring Boot Starter是一个Camunda BPM的Spring Boot Starter,它提供了REST API的支持,可以让您的Camunda BPM应用程序更容易地与其他应用程序集成。
- 使用camunda-bpm-spring-boot-starter-rest扩展,您可以使用Camunda BPM REST API与Camunda BPM引擎进行交互。这使得您可以使用Camunda BPM REST API执行各种操作,例如启动流程实例、查询任务、完成任务等。
- 如果您不使用camunda-bpm-spring-boot-starter-rest扩展,您仍然可以使用Camunda BPM REST API与Camunda BPM引擎进行交互。但是,您需要手动配置REST API,并且需要编写代码来与REST API进行交互。
也就是REST API 让我们可以用PostMan等方式,直接调用接口。不用的话,我们则可以自己写接口。
它的使用可参考-REST API Reference
默认API地址为
http://localhost:8080/engine-rest
Camunda使用的是jersey,因而一些配置需要jersey配置方式。
也可以通过修改spring boot的通用应用程序属性来改变API访问地址:
spring: jersey: application-path=地址
为了修改配置或注册额外的资源,可以提供一个集成自如下的配置类:
org.camunda.bpm.spring.boot.starter.rest.CamundaJerseyResourceConfig
@Component @ApplicationPath("/engine-rest") public class JerseyConfig extends CamundaJerseyResourceConfig {
@Override protected void registerAdditionalResources() {
register(...); } }
中心起点是ProcessEngine(流程引擎),可以通过配置部分中描述的几种方式创建ProcessEngine。
从ProcessEngine中,可以获得包含 工作流/BPM 方法的各种服务。
ProcessEngine和服务对象是 线程安全 的。所以可以为整个服务器保留对其中一个的引用。
actiti.cfg.xml文件:
- 对于所有的actiti.cfg.xml文件,流程引擎将以Spring方式构建:首先创建Spring应用程序上下文,然后从该应用程序上下文获得流程引擎。
- 如何书写,可参考-activiti配置文件activiti.cfg.xml
服务都是无状态的:
- 可以在集群中的多个节点上运行Camunda BPM,每个节点都访问同一个数据库,而不必担心哪台机器实际执行了前面的调用。对任何服务的任何调用都是幂等的,无论它在哪里执行。
2.2.2 服务
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RepositoryService可能是使用Camunda引擎时需要的第一个服务。此服务提供用于管理和操作部署和流程定义的操作。
部署 部署内容 意味着将其上传到引擎,在将所有进程存储到数据库之前,都将会对其进行检查和解析。
完成后,系统就知道部署了,之后就可以启动部署中包含的任何进程。
通过该服务,可以:
- 查询引擎已知的部署和流程定义。
- 挂起并激活流程定义。挂起意味着不能对它们进行进一步的操作,而激活则是相反的操作。
- 检索引擎自动生成的部署图或流程图中包含的文件等各种资源
RuntimeService runtimeService = processEngine.getRuntimeService();
RuntimeService处理启动流程定义的新流程实例。
流程定义定义了流程中不同步骤的结构和行为,流程实例是此类流程定义的一次执行。对于每个流程定义,通常都有多个实例同时运行。
RuntimeService也是用于检索和存储流程变量的服务。这是特定于给定流程实例的数据,可以由流程中的各种构造使用(例如,独占网关通常使用流程变量来确定选择哪条路径来继续流程)。
RuntimeService还允许对流程实例和执行进行查询。基本上,执行就是指向流程实例当前位置的指针。
最后,当流程实例等待外部触发器且流程需要继续时,将使用RuntimeService。流程实例可以有各种等待状态,该服务包含各种“通知”实例接收到外部触发器并可以继续该流程实例的操作。
TaskService taskService = processEngine.getTaskService();
需要展示给实际用户执行的任务是流程引擎的核心。
围绕任务的所有内容都分组在TaskService中,例如
- 查询已分配给用户/组的任务。
- 创建新的独立任务。这些任务与流程实例无关。
- 操作将任务分配给哪个用户,或者哪些用户以某种方式参与了任务。
- 申请并完成一项任务。声明意味着某人决定成为任务的受让人,这意味着该用户将完成任务。完成的意思是“完成任务的工作”。这通常是填写某种表单。
IdentityService identityService = processEngine.getIdentityService();
IdentityService允许对组和用户进行管理(创建、更新、删除、查询等)。
但是,核心引擎在运行时实际上不会对用户进行任何检查。
FormService formService = processEngine.getFormService();
FormService是一个可选服务。
此服务引入了启动表单和任务表单的概念。
- 启动表单是在流程实例启动之前向用户显示的表单
- 任务表单是在用户希望完成表单时显示的表单
该服务以一种易于使用的方式公开此数据。但同样,这是可选的,因为表单不需要嵌入到流程定义中。
HistoryService historyService = processEngine.getHistoryService();
HistoryService公开引擎收集的所有历史数据。
在执行流程时,引擎可以保存大量数据(这是可配置的),例如流程实例的开始时间、谁执行了哪些任务、完成任务所需的时间、每个流程实例遵循的路径等等。
该服务主要提供访问此数据的查询功能。
ManagementService managementService = processEngine.getManagementService();
在编写自定义应用程序时,通常不需要ManagementService。
它允许检索关于数据库表和表元数据的信息。此外,它还公开了作业的查询功能和管理操作。作业在引擎中用于各种用途,如计时器、异步延续、延迟挂起/激活等。
FilterService filterService = processEngine.getFilterService();
FilterService允许创建和管理过滤器。过滤器是像任务查询一样存储的查询。
例如,Tasklist使用过滤器来过滤用户任务。
camunda-Filters
ExternalTaskService externalTaskService = processEngine.getExternalTaskService();
ExternalTaskService提供对外部任务实例的访问。外部任务表示在外部独立于流程引擎处理的工作项。
CaseService caseService = processEngine.getCaseService();
CaseService类似于RuntimeService,但用于案例实例。它处理启动用例定义的新用例实例和管理用例执行的生命周期。该服务还用于检索和更新案例实例的流程变量。
DecisionService decisionService = processEngine.getDecisionService();
DecisionService允许评估部署到引擎的决策。它是在独立于流程定义的业务规则任务中评估决策的一种替代方法。
2.2.3 部署流程
@SpringBootApplication @EnableProcessApplication public class CamundaApplication {
public static void main(String[] args){
SpringApplication.run(CamundaApplication.class,args); } }
Camunda Engine的每个流程应用程序都需要该文件,此处我们始终将它保持为空(它会使用默认配置)
这里我们仍然从Modeler处创建一个流程。
然后保存在如下位置
启动后,我们可以看到已经成功部署
在流程定义中可以找到
此处也可以找到
如下就是部署与移除的流程,默认的配置下,即使删除bpmn,流程仍然存在于数据库中
@Service @Slf4j public class TestCamunda {
@Autowired private RuntimeService runtimeService; @EventListener private void processPostDeploy(PostDeployEvent event) {
log.info("{}",event); runtimeService.startProcessInstanceByKey("Process_028ntv2"); } }
我们可以做一个接口,通过接受服务ID,然后用RuntimeService去创建。
消费服务我们之前就写给过了,这里就跳过。
2.3 流程部署详细介绍
默认情况下,camunda-spring-boot-starter 使用SpringProcessEngineConfiguration 配置自动部署功能。
从1.2.0开始,可以通过 SpringBootProcessApplication 配置。这将禁用SpringProcessEngineConfiguration 的自动部署功能。
自动部署功能,用如下路径作为资源扫描的目录。
META-INF/processes.xml
允许使用的所有 processes.xml 配置项在这里列出。
如果是空的,就会用默认配置,如下:
<process-application xmlns="http://www.camunda.org/schema/1.0/ProcessApplication" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <process-archive> <properties> <property name="isDeleteUponUndeploy">false</property> <property name="isScanForProcessDefinitions">true</property> </properties> </process-archive> </process-application>
官方给出的配置样例:
<process-application xmlns="http://www.camunda.org/schema/1.0/ProcessApplication" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <process-archive name="loan-approval"> <process-engine>default</process-engine> <properties> <property name="isDeleteUponUndeploy">true</property> <property name="isScanForProcessDefinitions">true</property> </properties> </process-archive> </process-application>
我们在这里声明了一个单个部署(流程存档),流程存档的名称为loan-approval,并部署到名称为default的流程引擎。
- isDeleteUponUndeploy:此属性控制流程应用程序的取消部署是否需要从数据库中删除流程引擎部署。
- 默认设置为false。
- 如果将此属性设置为true,则取消部署流程应用程序将导致从数据库中删除部署(包括流程实例)。
- isScanForProcessDefinitions:如果此属性设置为true,则会自动扫描流程应用程序的类路径以查找可部署资源。
配置文件的基本设置,可参考-The processes.xml Deployment Descriptor
配置参数可查阅
- Process Engine Configuration
- Process Archive Configuration
只需要添加@EnableProcessApplication注解到SpringBootapplication类即可:
@SpringBootApplication @EnableProcessApplication public class CamundaApplication{
}
由于使用@EnableProcessApplication时,没有扩展ProcessApplication类,所以我们不能使用@PostDeploy和@PreUndeploy方法注释。
相反,这些回调是通过Spring事件发布机制提供的。所以可以使用以下事件监听器。
@SpringBootApplication @EnableProcessApplication public class CamundaApplication{
//... } @EventListener public void onPostDeploy(PostDeployEvent event) {
//... } @EventListener public void onPreUndeploy(PreUndeployEvent event) {
//... }
附录
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/114243.html


























