摘要
Activiti工作流引擎的生命,如同人生一般,充满了起起伏伏,但每个步骤都有其独特的意义。BPMN 2.0规范是这个过程中的指南,让我们一起探索吧!
正文
Activiti中工作流引擎的生命期详尽分析!一个BPMN步骤实例陪你了解新项目中步骤的生命期
BPMN 2.0详细介绍
- 工作流程实体模型注释(BusinessProcess Modeling Notation – BPMN)是工作流程实体模型的一种规范图型注释.这一规范是由目标管理方法组(Object Management Group – OMG)维护保养的
- BPMN标准的2.0版本号容许加上精准的关键技术在BPMN的图型和原素中,另外制订BPMN原素的实行英语的语法.根据应用XML语言表达来特定工作流程的可实行英语的语法,BPMN标准早已演化为工作流程的语言表达,能够实行在一切兼容BPMN2的流程引擎中,另外仍然能够应用强劲的图型注释
- 简易而言,BPMN即标志与标识的融合
界定一个步骤
- 建立一个新的XML文档并取名,确定文件后缀为 .bpmn20.xml或 .bpmn, 不然模块没法公布
- BPMN 2.0根节点是definitions连接点. 这一原素中,能够界定好几个步骤界定(但是提议每一个文档只包括一个步骤界定, 能够简单化开发设计全过程中的维护保养难度系数)
- 一个空的步骤界定以下所显示:留意definitions原素至少还要包括xmlns和 targetNamespace的申明
- targetNamespace能够是随意值,它用于对步骤案例开展归类
<definitions
xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
targetNamespace="Examples">
<process id="myProcess" name="My First Process">
..
</process>
</definitions>
- 能够挑选加上网上的BPMN 2.0文件格式部位:
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL
http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd
- process原素有两个特性:
- id: 这一特性是务必的,相匹配着Activiti ProcessDefinition目标的key特性.id能够用于运行步骤界定的步骤案例,根据RuntimeService的startProcessInstanceByKey方式
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myProcess");
留意: 它和startProcessInstanceById方式 不一样:这一方式 期待应用Activiti模块在公布时自动生成的id.能够根据启用processDefinition.getId() 方式 得到这一值,转化成的id的文件格式为 key:version, 较大长短限定为64字符, 假如在运作时抛出去了一个ActivitiException: 表明转化成的id太长了,必须限定步骤的key的长短
- name: 这一特性是可选择的, 相匹配ProcessDefinition的name特性.模块自身不容易应用这一特性,是用于在客户插口表明有利于阅读文章的名字
BPMN步骤实例前提条件
- 早已安裝Activiti而且可以运作Activiti Demo
- 应用了单独运作的H2网络服务器
- 改动db.properties,设定在其中的jdbc.url=jdbc:h2:tcp://localhost/activiti,随后运行独立主机
总体目标
- 学习培训Activiti和一些基本上的BPMN 2.0定义
- 最后結果是一个简易的Java SE程序流程能够公布步骤界定,根据Activiti模块API操作步骤
- 应用一些Activiti有关的专用工具,搭建自身的工作流程web应用
测试用例
- 每一个月都需要给公司领导一个金融业表格,由财务会计单位承担
- 当表格过去进行时,一个上级部门必须审核文本文档,随后才可以发送给全部领导干部
流程表
- 步骤的图形界面BPMN 2.0标识:
空逐渐事情(左边圆形),后边是2个客户每日任务:制做月度财务报告和认证月度财务报告,最终是空完毕事情(右边粗线条圆形)
XML內容
- 在工作流程的XML中非常容易寻找步骤的主要元素:
- (空)逐渐事情是步骤的通道
- 客户每日任务是步骤中与作业者有关的每日任务申明:
- 第一个分配任务给accountancy组
- 第二个分配任务给management组
- 当步骤做到空完毕事情便会完毕
- 这种原素都应用联线联接,这种联线有着source和target特性,界定了联线的方位
<definitions id="definitions"
targetNamespace="http://activiti.org/bpmn20"
xmlns:activiti="http://activiti.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>
运行一个步骤案例
- 建立好工作流程的步骤界定,就可以建立步骤案例
- 一个步骤案例相匹配了特殊月度财务报告的建立和审核,全部步骤案例都共享资源同一个步骤界定
- 为了更好地应用步骤界定建立步骤案例,最先要公布工作流程:
- 步骤界定会储存到分布式锁的数据储存里,是为Activiti模块尤其配备的.因此布署好工作流程,在模块重新启动后还能寻找步骤界定
- BPMN 2.0步骤文档会分析成运行内存领域模型, 能够根据Activiti API实际操作
- 根据下边的API公布步骤,全部与Activiti模块的互动全是根据services
Deployment deployment = repositoryService.createDeployment()
.addClasspathResource("FinancialReportProcess.bpmn20.xml")
.deploy();
- 运行一个新步骤案例,应用大家界定在步骤界定里的id(相匹配XML文档中的process原素).留意这儿的id针对Activiti而言,应当称为key,一般在步骤实体模型中应用的ID,在Activiti上都是Key:例如每日任务ID
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("financialReport");
- 那样建立一个步骤案例:
- 最先进到逐渐事情
- 逐渐事情以后,它会顺着全部的出门联线实行,抵达第一个每日任务(“制做月度财务报告”)
- Activiti会把一个每日任务储存到数据库查询里.这时候,分派到这一每日任务的客户或群聊会被分析,也会储存到数据库查询里
- 必须留意,Activiti模块会执行步骤的阶段,除非是碰到一个 等候情况:例如客户每日任务
- 等待情况下,当今的步骤案例的情况会储存到数据库查询中.直至客户决策达到目标才可以更改这一情况
- 这时候,模块会执行,直至碰到下一个等候情况,或步骤完毕
- 假如正中间模块重新启动或奔溃,步骤情况也会安全性的储存在数据库查询里
- 每日任务建立以后,startProcessInstanceByKey会在抵达客户每日任务这一等候情况以后才会回到.这时候,分配任务给了一个组,这代表着这一组是实行这一每日任务的备选组
- 如今将全部物品都放到一起,来建立一个简易的java程序流程:
- 建立一个Java新项目,把Activiti的jar和依靠放进classpath下:这种都能够在Activiti公布包的libs文件目录下寻找
- 在启用Activiti服务项目以前,大家务必结构一个ProcessEngine,能够使我们浏览服务项目
- 这儿大家应用[独立运作]的配备,这会应用demo安裝时的数据库查询来搭建ProcessEngine
public static void main(String[] args) {
// Create Activiti process engine
ProcessEngine processEngine = ProcessEngineConfiguration
.createStandaloneProcessEngineConfiguration()
.buildProcessEngine();
// Get Activiti services
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
// Deploy the process definition
repositoryService.createDeployment()
.addClasspathResource("FinancialReportProcess.bpmn20.xml")
.deploy();
// Start a process instance
runtimeService.startProcessInstanceByKey("financialReport");
}
任务列表
- 能够根据TaskService来得到每日任务,加上下列逻辑性:
List<Task> tasks = taskService.createTaskQuery().taskCandidateUser("kermit").list();
- 留意传到的客户务必是accountancy组的一个组员,要和步骤界定中相对性应:
<potentialOwner>
<resourceAssignmentExpression>
<formalExpression>accountancy</formalExpression>
</resourceAssignmentExpression>
</potentialOwner>
- 还可以应用群组名称,根据每日任务查看API来得到有关的結果.在编码中加上以下逻辑性:
TaskService taskService = processEngine.getTaskService();
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("accountancy").list();
- 由于配备的ProcessEngine应用了与demo同样的数据信息,能够登陆到Activiti Explorer.默认设置,accountancy(财务会计)组里沒有所有人:
- 登陆
- 点一下组
- 建立一个新组
- 点一下客户
- 把成分配发fozzie
- 应用fozzie/fozzie登陆
- 就可以运行大家的工作流程了,挑选Processes页,在[月度财务报告]的[实际操作]列点一下[运行步骤]
- 步骤会实行到第一个客户每日任务.由于大家以kermit登陆,在运行步骤案例以后,就可以见到拥有一个新的待领每日任务.挑选每日任务页来查询这一条新每日任务.留意即便 步骤被别人运行,每日任务依然会被财务会计组里的任何人做为一个备选每日任务见到
领到每日任务
- 如今一个财务会计要领取这一每日任务
- 领取之后,这一客户便会变成每日任务的原告,每日任务会从财务会计组的别的组员的任务列表中消退.领取每日任务的编码:
taskService.claim(task.getId(), "fozzie");
- 每日任务会进到领取每日任务人的本人任务列表:
List<Task> tasks = taskService.createTaskQuery().taskAssignee("fozzie").list();
- 在Activiti Explorer UI中,点一下领取按键,会实行同样的实际操作.每日任务会挪动到登陆客户的本人任务列表.你也会见到每日任务的原告早已变为当今登录的客户:
达到目标
- 如今财务会计能够逐渐开展财务报告的工作中
- 汇报进行后,他能够达到目标,代表着每日任务需要的全部工作中都进行
taskService.complete(task.getId());
- 针对Activiti模块:
- 必须一个外界信息内容来让步骤案例执行
- 每日任务会把自己从运行库中删掉
- 步骤会顺着独立一个出门联线实行,挪动到第二个每日任务(审批报告)
- 与第一个每日任务同样的体制会应用到第二个每日任务上,不一样的是每日任务是分派给management组
- 在demo中:
- 达到目标是根据点一下任务列表中的进行按键
- 由于Fozzie并不是财务会计,大家先从Activiti Explorer销户
- 随后应用kermit登录(主管),第二个每日任务会进到未分派任务列表
完毕步骤
- 审核每日任务像以前一样查看和领到.
- 进行第二个每日任务会让步骤实行到完毕事情,便会完毕步骤案例
- 步骤案例和全部有关的运作数据信息都是会从数据库查询中删掉
- 登陆Activiti Explorer就可以开展认证,能够见到储存步骤运作数据信息的表中早已沒有数据信息:
- 能够应用historyService分辨步骤是不是早已完毕:
HistoryService historyService = processEngine.getHistoryService();
HistoricProcessInstance historicProcessInstance =
historyService.createHistoricProcessInstanceQuery().processInstanceId(procId).singleResult();
System.out.println("Process instance end time: " historicProcessInstance.getEndTime());
源代码
- 充分考虑你很有可能会在Activiti Explorer UI中运行一些步骤案例,那样,它会得到好几个每日任务,而不是一个,因此编码能够一直一切正常运作:
public class TenMinuteTutorial {
public static void main(String[] args) {
// Create Activiti process engine
ProcessEngine processEngine = ProcessEngineConfiguration
.createStandaloneProcessEngineConfiguration()
.buildProcessEngine();
// Get Activiti services
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
// Deploy the process definition
repositoryService.createDeployment()
.addClasspathResource("FinancialReportProcess.bpmn20.xml")
.deploy();
// Start a process instance
String procId = runtimeService.startProcessInstanceByKey("financialReport").getId();
// Get the first task
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());
// claim it
taskService.claim(task.getId(), "fozzie");
}
// Verify Fozzie can now retrieve the task
tasks = taskService.createTaskQuery().taskAssignee("fozzie").list();
for (Task task : tasks) {
System.out.println("Task for fozzie: " task.getName());
// Complete the task
taskService.complete(task.getId());
}
System.out.println("Number of tasks for fozzie: "
taskService.createTaskQuery().taskAssignee("fozzie").count());
// Retrieve and claim the second task
tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
for (Task task : tasks) {
System.out.println("Following task is available for accountancy group: " task.getName());
taskService.claim(task.getId(), "kermit");
}
// Completing the second task ends the process
for (Task task : tasks) {
taskService.complete(task.getId());
}
// verify that the process is actually finished
HistoryService historyService = processEngine.getHistoryService();
HistoricProcessInstance historicProcessInstance =
historyService.createHistoricProcessInstanceQuery().processInstanceId(procId).singleResult();
System.out.println("Process instance end time: " historicProcessInstance.getEndTime());
}
}
汇总
- 能够根据Activiti中的BPMN 2.0构造,对工作流程开展下列层面的:
- 界定网关ip来完成管理决策阶段: 主管能够驳回申诉财务报告,再次给财务会计建立一个每日任务
- 考虑到应用自变量: 能够储存或引入汇报,把它表明到表格中
- 在步骤最终添加服务项目每日任务: 把汇报发送给每一个领导干部
关注不迷路
扫码下方二维码,关注宇凡盒子公众号,免费获取最新技术内幕!
温馨提示:如果您访问和下载本站资源,表示您已同意只将下载文件用于研究、学习而非其他用途。
评论0