技术标签: java
Flowable 是一个使用 Java 编写的轻量级业务流程引擎,使用 Apache V2 license 协议开源。2016 年 10 月,Activiti 工作流引擎的主要开发者离开 Alfresco 公司并在 Activiti 分支基础上开启了 Flowable 开源项目。基于 Activiti v6 beta4 发布的第一个 Flowable release 版本为 6.0。以 JAR 形式发布使得 Flowable 可以轻易加入任何Java环境:Java SE、Tomcat、Jetty 或 Spring 之类的 servlet 容器;JBoss 或 WebSphere 之类的 Java EE 服务器等等。
流程引擎是支持配置业务流转过程的关键模块。Flowable 支持 BPMN 2.0 行业标准,同时提供了一些 Flowable 自定义的 BPMN 扩展(extensions)可选用,允许通过导入 XML 文件或通过前端可视化界面建立流程。
作为以 BPMN 为核心的工作流引擎,Flowable 原本与规则引擎的关联并不强,但实际业务流程中,有时需要由多个决策来决定流程走向,而每个决策都要根据自身的规则来决定,每个决策之间也可能存在关联。此时就需要规则引擎来提供决策支撑。
CMMN 是 Case Management Model 的缩写,在 Flowable Modeler 应用中体现为「案例模型」菜单,使用时可以类似于流程引擎可视化配置流程,也可通过XML格式文件。
Flowable 框架中将表单作为一个独立的子模块,可以将表单作为一个服务在其他模块中进行调用,表单服务就可以控制所有流程所使用的表单以及表单字段的可读、可写等操作。表单相关的使用可分为表单的定义以及表单的运行实例两个阶段。表单定义支持导入以 .form 为后缀的表单定义文件(JSON 语言编写) 。
<definitions id="definitions"
targetNamespace="http://flowable.org/bpmn20"
xmlns:flowable="http://flowable.org/bpmn"
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL">
<process id="financialReport" name="Monthly financial report reminder process">
<startEvent id="theStart" />
<sequenceFlow id="flow1" sourceRef="theStart" targetRef="writeReportTask" />
<userTask id="writeReportTask" name="Write monthly financial report" >
<documentation>
Write monthly financial report for publication to shareholders.
</documentation>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>accountancy</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<sequenceFlow id="flow2" sourceRef="writeReportTask" targetRef="verifyReportTask" />
<userTask id="verifyReportTask" name="Verify monthly financial report" >
<documentation>
Verify monthly financial report composed by the accountancy department.
This financial report is going to be sent to all the company shareholders.
</documentation>
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>management</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
</userTask>
<sequenceFlow id="flow3" sourceRef="verifyReportTask" targetRef="theEnd" />
<endEvent id="theEnd" />
</process>
</definitions>
<dependency>
<groupId>org.flowable</groupId>
<artifactId>flowable-spring-boot-starter</artifactId>
<version>6.4.2</version>
</dependency>
public static void main(String[] args) {
// 创建Flowable流程引擎
ProcessEngine processEngine = ProcessEngineConfiguration
.createStandaloneProcessEngineConfiguration()
.buildProcessEngine();
// 获取Flowable服务
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
// 部署流程定义
repositoryService.createDeployment()
.addClasspathResource("one-task-process.bpmn20.xml")
.deploy();
// 启动流程实例
String procId =runtimeService.startProcessInstanceByKey("financialReport").getId();
// 获取第一个任务
TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("accountancy").list();
for (Task task : tasks) {
System.out.println("Following task is available for accountancy group: " + task.getName());
// 申领任务
taskService.claim(task.getId(), "fozzie");
}
// 验证Fozzie获取了任务
tasks = taskService.createTaskQuery().taskAssignee("fozzie").list();
for (Task task : tasks) {
System.out.println("Task for fozzie: " + task.getName());
// 完成任务
taskService.complete(task.getId());
}System.out.println("Number of tasks for fozzie: "
+ taskService.createTaskQuery().taskAssignee("fozzie").count());
// 获取并申领第二个任务
tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
for (Task task : tasks) {
System.out.println("Following task is available for management group: " + task.getName());
taskService.claim(task.getId(), "kermit");
}
// 完成第二个任务并结束流程
for (Task task : tasks) {
taskService.complete(task.getId());
}
// 验证流程已经结束
HistoryService historyService = processEngine.getHistoryService();
HistoricProcessInstance historicProcessInstance =
historyService.createHistoricProcessInstanceQuery().processInstanceId(procId).singleResult();
System.out.println("Process instance end time: " + historicProcessInstance.getEndTime());
}
文章浏览阅读664次,点赞2次,收藏4次。Linux系统下QT编程串口设备号查询不到_availableports
文章浏览阅读287次。英文 |https://medium.com/frontend-at-scale/frontend-architectural-patterns-backend-for-fronten..._后端是适配各种前端
文章浏览阅读4.8k次,点赞3次,收藏19次。让我们看看基本的基于Python的I2C函数,这些函数经常用于Raspberry Pi上的I2C通信。在python中开发Raspberry Pi I2C通信程序时,我们可以使用SMBus库包,它对访问I2C设备有很大的支持。因此,我们应该使用apt数据包管理器为Python添加SMBus支持,sudo apt-get install python-smbus基于Python的I2C函数导入SMBus要使用SMBus Python模块访问Raspberry Pi上的I2C总线,请按如下方式导_树莓派 python i2c
文章浏览阅读103次。架构图环境IP环境需装软件192.168.0.237mysql-5.7.20node_exporter-0.15.2.linux-amd64.tar.gz mysqld_exporter-0.10.0.linux-amd64.tar.gz192.168.0.248grafana+prometheusprometheus-2.1.0.linux-amd64...._prometheu+grafana监控mysql
文章浏览阅读87次。1.前提准备 jdk的开发环境必须为1.6以及以上的版本(1.6及以上版本的jdk包含了javax.jws包).2.创建提供服务的接口以及服务接口的实现类 在发布webservice时,jvm必须要识别那些发布了那些服务,所以要对服务接口和服务接口实现类进行标识,就需要@WebService,@WebMethod两个注解。 2.1 服务接口必须加注解@WebService,要..._@webserviceclient 在jdk17需要引入什么包
文章浏览阅读2.4k次。一、需求在使用spring gateway作为网关时,我们需要在经过网关的请求中添加一些需要传递给后续服务的公共参数,这个时候就可以用到spring gateway提供的自定义请求参数功能了。二、寻找解决途径1、参考官方文档我们可以猜测,spring gateway作为网关功能,肯定会提供很多处理请求参数的功能,于是我们查询文档得到如下内容:2、探索GatewayFilterFactory实现规律通过查询spring官方文档可以看到,spring gateway为我们提供了很多xxx_gateway请求头封装参数
文章浏览阅读3.6w次,点赞11次,收藏46次。马上就圣诞节了,别人都手绘圣诞树,身为程序猿的我们可以用C语言编写一个圣诞树出来代码如下#include <stdio.h>int main(){ int o,x,y,g,e,n; int m; printf("请输入圣诞树层数:"); scanf("%d",&o); for(x=0;x<=1;x++) { for(y=0;y<=o-x;y++) { pr..._c语言圣诞树
文章浏览阅读1.8k次。最近有看过一些相关方面的书,但其实每本书说的都不尽相同,基于自己的理解,在这里总结一下。数据可视化是一门跨专业的学科,这很多地方都有提到,毋庸置疑,正因于此,不同的领域或者人对于其定义不同,可能有的人偏重于视觉表现,比如前端,设计行业;有的人呢则偏重于功能体现,这都是以为跨学科带来的不同观点,也可能会导致同一份数据在不同领域可视化呈现的方式有所不同。在定义什么是数据可视化和不是之间,定义相对比..._数据可视化
文章浏览阅读3.9k次,点赞4次,收藏32次。OpenCV数字图像处理之ROI区域的提取利用mask(掩模)技术提取纯色背景图像ROI区域中的人和物,并将提取出来的人或物添加在其他图像上。1、实现原理先通过cv.cvtColor()函数,将原RGB彩色图像转换为hsv色彩空间的图像,然后通过cv.inRange()函数获得ROI区域的Mask,最后利用cv.bitwise()函数提取得到ROI区域。2、使用的函数简述(1) cv.cvtColor(img, cv.COLOR_BGR2HSV)函数img为要进行色彩空间转换的原图cv.COL_roi提取算法
文章浏览阅读3.4k次。将数组格式的字符串转换成数组由于数据传输的原因,有时我们得到的是字符串形式的数组(比如:str=’[“a”,“b”,“c”,“d”]’,写成str="[‘a’, ‘b’, ‘c’, ‘d’]",使用JSON.parse()的时候会报错)。要将这种字符串还原成数组对象,有如下两种方法。使用 eval() 函数转换eval() 函数可计算某个字符串,并执行其中的的 JavaScript 代码。我们可以借助它来将字符串还原成数组。const str = '["a", "b", "c", "d"]';._字符串数组转数字数组
文章浏览阅读519次。持续更新:https://github.com/ar414-com/php-source-lib学习资源PHP相关的有参考价值的社区,博客,网站,文章,书籍,视频等资源PHP网站(PHP Websites)PHP The Right Way - 一个PHP实践的快速参考指导PHP Best Practices - 一个PHP最佳实践PHP Weekly News - 一个PH..._php 安全调用类库
文章浏览阅读1.7k次。形态学滤波:对灰度图像进行开运算与闭运算。一、c++示例代码//包含头文件#include <opencv2/opencv.hpp>//命名空间using namespace cv;using namespace std;//全局函数声明部分//主函数int main(){ //【1】载入图像,灰度化 Mat image = imread("F:\\opencvt..._灰度图像形态学滤波