flowable画图教程_Flowable从入门到入土(1)-初始Flowable
Flowable从入门到入土
作者:独钓寒江雪
一剑一酒一江湖, 便是此生
心中有图,何必点灯。装载请注明出处
前文传送门:
简介
当前周围好多人都对flowable有所了解乃至投入到生产使用,此文章作为抛砖引玉之用。引出各位大侠进行指正。
如果你对工作流引擎有所了解,那么一定知道Java领域当前主流的工作流引擎无非就是Jboss旗下的JBPM和Alfresco旗下的Activity。
Flowable是Activiti原班主创人员从Activiti分离出来的一套工作流引擎,是一个业务流程管理(BPM)和工作流系统,适用于开发人员和系统管理员。其核心是超快速、稳定的BPMN2流程引擎,易于与 Spring集成使用。
Flowable的诞生简直和Acitiviti的诞生如出一辙!当年JBMP的主创Tom已经离开Alfresco多年,后辈们也开始步前人后尘。Tijs Rademakers、Joram Barrez等Activiti的原班核心人马,由于与Alfresco公司在项目的未来发展方向上出现分歧,于是选择集体出走,创建了Flowable,并且将第一个版本定义为5.22,而且在两周前发布了6.0版本!要知道,Activiti当前版本依然还是5.22,6.0处于Beta阶段。
Flowable团队对用户说道,“如果你还在犹豫是否加入我们,请看看Activiti源码里的作者们,再看看Flowable项目的成员们。我们是最懂Activiti、在过去几年里推动了整个社区、为社区做出贡献和改革的那帮人。”
选择Flowable的要点如下:
社区强大并开源。截止文章写时,flowable已经在计划后续版本不开源使用。但是有老版本开源在手,天下我有。毕竟工作流只是业务上的辅助平台。
更新力度强大 源源不断的更新。
主力开发团队是原activity的主力团队。
相比camuda这个工作流引擎。可定制化程度高很多。
在代码风格上,Flowable是比较尊重并且推崇DDD的开发准则的。这读起来还是让人比较舒服。
任何的工作流引擎主要工作都体现为节点的流转以及表单的填写。其还是以业务为主,工作流为辅,切不可工作流为主,业务为辅进行实际生产使用。
源码下载
Flowable的GitHub官网地址
源码目录说明
modules:该文件夹下存储了Activity项目所有模块的Java源文件。因为flowable和Activity是同一波开发团队,故此处会看到和Activity非常相似的模块。
qa: 一些通用的流程配置文件样例。
scripts: Linux平台下的一些启动脚本文件。
doc: 用户操作手册,包括了基础的UserGuide和PublicApi
docker和k8s: 容器镜像和管理
pom.xml: 所有Maven工程的parent。Flowable各个子模块项目中依赖的第三方包均定义在该文件中
服务介绍
Flowable整体是通过ProcessEngine来操作的。即不管什么框架操作流程,都需要通过ProcessEngine这个类来处理。ProcessEngine是Flowable对外公开的门面。UML类图如下:
关系图如下:
介绍下如下这些实际经常使用的到的类以及关键方法。
RepositoryService
流程建立相关。比如流程定义,流程的部署,流程文件的查询,验证BpmnModel等,流程转换成bpmnModel,BpmnModel转化成流程文件(.bpm)等。关键方法如下:
//伪代码。关键代码
// 验证bpmnModel
List validationErrors = repositoryService.validateProcess(bpmnModel);
//流程的查询
repositoryService.createProcessDefinitionQuery().processDefinitionName(route.getId().toString()).singleResult();
// 通过bpmnmodel定义流程并部署流程
Deployment deployment = repositoryService.createDeployment().addBpmnModel(bpmnModel.getProcesses().get(0).getName()+".bpmn", bpmnModel).deploy();
//将流程转成bpmnModel
repositoryService.getBpmnModel(processDefinition.getId());
//根据processDef上的deploymentId获取流程定义生成的bpmn文件或者其他资源文件。
InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, resourceName);
// 删除流程定义
repositoryService.deleteDeployment(processDefinition.getDeploymentId(), cascade);
复制代码
RumtimeService
流程实例管理。管理流程实例的启动,推进,删除,获取流程实例当前状态等。
// 启动实例。businessId为业务号,一般唯一。比如lotId。商品编码。业务层方便查找
runtimeService.startProcessInstanceById(processDefinition.getId(), businessId);
// trigger形式的过站 只适用于ReceiveTask S1表示当前流程所在的taskId
ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(businessId).singleResult();
Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).activityId("S1").singleResult();
runtimeService.trigger(execution.getId());
复制代码
HistoryService
流程历史查询,所有有关历史的查询都从这个Service中来。
// 整个业务的持续时间
List list = historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(lotId).list();
String instanceId = "";
for (HistoricProcessInstance hpi : list) {
instanceId = hpi.getId();
System.out.println("流程定义文件->" + hpi.getProcessDefinitionId());
System.out.println("ProcessInstance->" + hpi.getId());
System.out.println("StartActivityId->" + hpi.getStartActivityId());
System.out.println("EndActivityId->" + hpi.getEndActivityId());
System.out.println("startTime ->" + hpi.getStartTime() + "EndTime->" + hpi.getEndTime() + "duration" + hpi.getDurationInMillis());
}
//业务流转过程中每站的记录
List list1 = historyService.createHistoricActivityInstanceQuery().processInstanceId(instanceId).list().stream().sorted(Comparator.comparing(HistoricActivityInstance :: getStartTime)).collect(Collectors.toList());
for (HistoricActivityInstance historicActivityInstance : list1) {
System.out.println("------");
System.out.println(historicActivityInstance.getActivityId());
System.out.println(historicActivityInstance.getActivityName());
System.out.println(historicActivityInstance.getActivityType());
System.out.println("startTime ->" +historicActivityInstance.getStartTime() + "EndTime->" + historicActivityInstance.getEndTime() + "duration" + historicActivityInstance.getDurationInMillis());
}
复制代码
TaskService
用于指定节点任务的主要Service.比如ReceiveTask, UserTask, MailTask,HttpTask等等。不同的Task具备了不同的处理方式。
Execution execution = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).activityId("S1").singleResult();
runtimeService.trigger(execution.getId());
execution = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).activityId("S2").singleResult();
runtimeService.trigger(execution.getId());
execution = runtimeService.createExecutionQuery().processInstanceId(processInstance.getId()).activityId("S3").singleResult();
runtimeService.trigger(execution.getId());
复制代码其他Service会在后续的文章中在逐一讲解。
构建流程
通过流程的bpmn文件进行部署流程
可以通过flowable提供的eclipse插件,Idea插件或者webui(需引入FlowableModuler。不推荐)上进行创建流程并保存为bpmn文件。并放入项目的classpath下进行引入部署。
注意:deployment的时候ResourceName要是bpmn结尾。不然不会被解析。相关源码参考ResourcesUtils
public static final String[] BPMN_RESOURCE_SUFFIXES = new String[] { "bpmn20.xml", "bpmn" };
public static final String[] DIAGRAM_SUFFIXES = new String[] { "png", "jpg", "gif", "svg" };
复制代码
使用bpmn模型构建并部署流程
可以通过bpmn.js。其为Camuda开源的一个BPM的前端JS库。其可以直接使用并定义相应的流程。建议用此种。比较方便且快捷。bpmn.js使用后续会有相应的文章来吹牛*。敬请期待。
可以通过自己公司的前端开发进行构建传递数据。
BpmnModel bpmnModel = new BpmnModel();
StartEvent start = new StartEvent();
start.setId("start1");
start.setName("开始节点");
SequenceFlow flow1 = new SequenceFlow();
3eflow1.setId("flow1");
flow1.setName("开始节点-->任务节点1");
flow1.setSourceRef("start1");
flow1.setTargetRef("receiveTask1");
ReceiveTask receiveTask1 = vbnew ReceiveTask();
receiveTask1.setId("receiveTask1");
receiveTask1.setName("节点1");
SequenceFlow flow2 = new SequenceFlow();
flow2.setId("flow2");
flow2.setName("节点1-->结束节点");
flow2.setSourceRef("receiveTask1");
flow2ow1.setTargetRef("endEvent");
EndEvent end = new EndEvent();
endEvent.setId("endEvent");
endEvent.setName("结束节点");
Process process=new Process();
process.setId("process1");
process.setName("process1");
process.addFlowElement(start);
process.addFlowElement(flow1);
process.addFlowElement(receiveTask1);
process.addFlowElement(flow2);
process.addFlowElement(end);
bpmnModel.addProcess(process);
repositoryService.createDeployment().addBpmnModel(bpmnModel.getProcesses().get(0).getName()+".bpmn", bpmnModel).deploy();
复制代码
踩坑总结
数据库脚本创建策略
因为flowable在数据库版本管控上使用的是Liquibase进行管控。所以在自动创建完flowable的数据库之后。一定要将ProcessEngineConfiguration的database-schema-update改成false。不然当不同的人更改了flowable的版本,会自动更新表结构。会导致问题。
所有节点的ID不能是数字
Flowable在定义的节点中不能是数字作为节点的Id。数字作为节点的ID会出现异常。异常部分堆栈如下
org.flowable.bpmn.exceptions.XMLException: javax.xml.stream.XMLStreamException: org.xml.sax.SAXParseException; lineNumber: 4; columnNumber: 6; cvc-datatype-valid.1.2.1: '1' 不是 'NCName' 的有效值。
at org.flowable.bpmn.converter.BpmnXMLConverter.convertToBpmnModel(BpmnXMLConverter.java:273)
at org.flowable.engine.impl.bpmn.parser.BpmnParse.execute(BpmnParse.java:148)
at org.flowable.engine.impl.bpmn.deployer.ParsedDeploymentBuilder.createBpmnParseFromResource(ParsedDeploymentBuilder.java:97)
at org.flowable.engine.impl.bpmn.deployer.ParsedDeploymentBuilder.build(ParsedDeploymentBuilder.java:55)
at org.flowable.engine.impl.bpmn.deployer.BpmnDeployer.deploy(BpmnDeployer.java:76)
at org.flowable.engine.impl.persistence.deploy.DeploymentManager.deploy(DeploymentManager.java:62)
复制代码本期内容就到此就结束了。如有大侠指定,请不吝赐教。。。下期介绍Flowable的表结构。
关于找一找教程网
本站文章仅代表作者观点,不代表本站立场,所有文章非营利性免费分享。
本站提供了软件编程、网站开发技术、服务器运维、人工智能等等IT技术文章,希望广大程序员努力学习,让我们用科技改变世界。
[Flowable从入门到入土(1)-初始Flowable]http://www.zyiz.net/tech/detail-120531.html
flowable画图教程_Flowable从入门到入土(1)-初始Flowable相关推荐
- flowable画图教程_flowable画图教程_Flowable 学习笔记
一.Flowable 入门介绍 官网地址:https://www.flowable.org/ Flowable6.3中文教程:https://tkjohn.github.io/flowable-use ...
- PIXIJS超级详细教程【从入门到入土-下】
来自GitHub教程 GitHub - Zainking/LearningPixi: ⚡️Pixi教程中文版 PIXIJS教程[从入门到入土-上]地址[https://blog.csdn.net/qq ...
- PixiJS超级详细教程【从入门到入土-上】
PixiJS 来自GitHub教程 GitHub - Zainking/LearningPixi: ⚡️Pixi教程中文版 PixiJS超级详细教程[从入门到入土-下]地址[https://blog. ...
- flowable画图教程_JeeGit企业级快速开发平台-JeeSite4 Flowable入门教程
注: 998元以下课程无咨询服务 该课程包含服务内容:299元含发票 在线课程观看权 购课后,教学资源联系长春叭姐QQ:3211247533 索要 教学内容 3.1 第一章 业务流程 BPM.工作流引 ...
- Flink 教程 gitbook 从入门到入土(详细教程)
Flink从入门到入土(详细教程) 和其他所有的计算框架一样,flink也有一些基础的开发步骤以及基础,核心的API,从开发步骤的角度来讲,主要分为四大部分 1.Environment Flink J ...
- flowable画图教程_给初学者的RxJava2.0教程(七): Flowable
作者博客http://www.jianshu.com/u/c50b715ccaeb前言上一节里我们学习了只使用Observable如何去解决上下游流速不均衡的问题,之所以学习这个是因为Observab ...
- 【技术文档】R语言使用教程:从入门到入土
1. 细胞通信工作 1. VSCode 搭配使用 1.1 安装教程 推荐教程1:Mac OS 系统下配置 VS Code 的 R 运行环境 推荐教程2:在VS Code中搭建你的R语言运行环境吧 自己 ...
- python控制流教程_python从入门到入土教程(2)——控制流和函数
一 内置函数和库 二 控制流 * if condition_1: statement_block_1 * elif condition_2: statement_block_2 * else: sta ...
- 【C++从入门到入土】第五篇:继承(爆肝画图详解)
系列文章目录 [C++从入门到入土]第一篇:从C到C++. [C++从入门到入土]第二篇:类和对象基础. [C++从入门到入土]第三篇:类和对象提高. [C++从入门到入土]第四篇:运算符重载. 文章 ...
最新文章
- 独家 | 麦肯锡教我的数据科学家的五大黄金法则
- POJ2342-Anniversary party-树形DP入门
- mysql中的字典项是啥_常见数据库设计(1)——字典数据
- 快速了解和使用Photon Server
- centos7 apache2.4 测试
- php写文件 效率,php中读写文件与读写数据库的效率_PHP教程
- Preserve Whole Object(保持对象完整)
- python 读取csv文件转成字符串_从CSV读取到 dataframe pandas python时dict对象转换为字符串...
- html轮播文字上下轮播,js、jQuery实现文字上下无缝轮播、滚动效果
- Spring中IoC创建对象方式(构造器注入)
- 为什么很少人写类似金庸的武侠小说
- nodejs基础-函数
- 锐起无盘服务器优化,锐起无盘系统制作系统优化教程.docx
- 驱动程序安装全攻略2
- opengl魔方文档_基于OpenGL的3D旋转魔方的实现.doc
- Windows MongoDB下载 安装以及配置(一条龙到底)
- 『Scrapy』爬取斗鱼主播头像
- js身份证号校验方法(转载我的请注明哈哈)
- 电气专业c语言要学得非常好吗,电气自动化专业需要学C语言吗?
- K3 如何将物料属性中的科目代码设置默认值
热门文章
- 一周年创作纪念日,冲吧少年郎
- 中文短文本分类实例十二-HAN(Hierarchical Attention Networks for Document Classification)
- 01 - 如何制定性能调优标准?
- Linux下读取smBIOS源码,linux – 了解SMBIOS的段组,总线,设备和功能号码
- 微信小程序数字保留两位小数
- 说说捞月狗与其他电商网站的感觉
- Excel-函数-拆分和组合函数
- 美国的Open RAN遭遇挫败,证明了华为的5G设备领先优势毋庸置疑
- 微信错误:errcode=40164,errmsg=invalid ip xxx.x.xxx.xxx, not in whitelist
- linux绑定arp mac静态,arp 静态绑定Mac地址