Activiti工作流学习笔记
先从工作流的启动开始讲,Activiti提供了四种工作流的启动方式
1.空启动事件
2.定时启动事件
3.异常启动事件
4.消息启动事件
空启动事件中标签内没有任何其他元素的定义
<startEvent id="startEvent" name="StartEvent"></startEvent>
Activity根据需求在空启动事件上进行了扩展,activiti:formKey表示与这个启动事件所关联的外置表单,activiti:initiator表示启动该流程的人员的id
<startEvent id ="StartEvent" name="startevent" activiti:formKey="user.form"></startEvent>
<startEvent id ="StartEvent" name ="startevent" activiti:initiator="user.id"></startEvent>
定时启动事件可以用于定期循环流程和一次性流程,比如企业的月报每月末汇总一次
<startEvent id="startEvent" name="time sart for process">
<timerEventDefinition>
<timeCycle>R1/2018-3-31T00:00/PM1M</timeCycle>
</timerEventDefinition>
<startEvent>
异常启动事件不能被runTimeService.startProcess()调用启动,他是通过另外一个流程的异常结束事件触发,下面是通过一个scripTask来捕获异常代码为AII001的异常并输出捕获语句
<startEvent id ="startEvent">
<errorEventDefinition erroeRef="AII001"></errorEventDefinition>
</startEvent>
<scriptTask id = "scripttask" name="scriptask" scriptFrommat="Groovy">
<script><![CDATA[out:println "catch an error";]]</script>
</scriptTask>
消息启动事件通过一个消息名称触发从而启动一个流程实例,通常结合消息抛出事件一起使用。
<message id = "reSendFile" name="重新发送消息">
<startEvent id = "messageStart">
<messageEventDefinition messageRef="reSendFile"/>
</startEvent>
结束事件包括空结束事件,异常结束事件,终止结束事件,取消结束事件
空结束事件不处理抛出结果,也可以理解为抛出空
<endEvent id = "endEvent" name= "end Event"/>
异常结束事件定义了抛出的异常错误代码,如果定义了异常开始事件怎会根据错误代码匹配到对应的异常开始事件触发对应的流程
<endEvent id = "endEvent" name="end Event">
<errorEventDefinition errorRef="AIA-001" />
</endEvent>
终止结束事件可以终止一个流程,当一个流程因为某些原因不能继续向下进行的时候则可以将该流程的一条输出流指向终止结束事件,空结束事件结束的是一次执行,而终止结束事件结束的是整个流程。
<endEvent id="endEvent" name="终止结束事件">
<terminateEventDefinition></terminateEventDefinition>
</endEvent>
取消结束事件可以取消一个事物子流程的执行,也只能在子流程中使用,当子流程出现异常需要取消时可以定义一个取消结束事件,当输出流指向一个取消结束事件是流程就会中断执行。
<endEvent id = "endEvent" name="cancel">
<cancelEventDefinition />
<endEvent>
顺序流
标准顺序流
标准顺序流是连接两个或多个模型建立关系
<sequenceFlow id = "flow" sourceRef="startEvent" targertRef="userTask"><sequenceFlow>
条件顺序流
条件顺序流是在标准顺序流上面添加条件表达式,只用通过条件才可以达到目标活动
<sequenceFlow id="flow" name="条件顺序流" sourceRef="startEvent" targetRef="usertask">
<conditionExpression xsi:type="tFormalExpression">
<![CDATA[${pass==true}]]>
</conditionExpression>
</sequenceFlow>
任务
任务是流程中比较重要的部分,根据业务需求的不同任务也可以分为很多种
1.用户任务
2.脚本任务
3.WebService任务
4.业务规则任务
5.邮件任务
6.Mule任务
7.Camel任务
8.手动任务
9.Java Service 任务
10.Shell任务
用户任务
用户任务需要人参与, Activiti在BPMN2.0的基础上的基础上对属性进行了扩展
activiti:assignee指定了任务的处理人
activiti:cadidateUsers指定了用户任务的候选人,多个用逗号隔开
activiti:cadidateGroups指定了用户任务的候选组,多个用逗号隔开
activiti:dueDate 指定了用户任务的到期日
activiti:priority 指定了用户任务的优先级
下面用户任务指定了候选组为deptLeader 并且执行任务的时候提交一个动态表单(后面会讲)
<userTask id="deptLeaderAudit" name="部门领导审批" activiti:candidateGroups="deptLeader">
<extensionElements>
<activiti:formProperty id="startDate" name="请假开始日期" type="date" value="${startDate}" datePattern="yyyy-MM-dd" readable="true" writable="false"></activiti:formProperty>
<activiti:formProperty id="endDate" name="请假结束日期" type="date" value="${endDAte}" datePattern="yyyy-MM-dd" readable="true" writable="false"></activiti:formProperty>
<activiti:formProperty id="reason" name="请假原因" type="string" value="${reason}" readable="true" writable="false"></activiti:formProperty>
<activiti:formProperty id="deptLeaderPass" name="审批意见" type="enum" required="true" writable="true">
<activiti:value id="true" name="同意"></activiti:value>
<activiti:value id="false" name="不同意"></activiti:value>
</activiti:formProperty>
</extensionElements>
</userTask>
脚本任务可以运行引擎依赖语言之外的脚本语言,activiti支持的语言包括Groovy,JavaScript,Juel,activiti扩展的属性有
scriptFormat:指定脚本所依赖的语言
resultVariable:将脚本中返回的结果保存在变量里,当然这个变量需要在脚本里定义
<scriptTask id="initvars" name="初始化变量" scriptFormat="groovy">
<script>
<![CDATA[def name="铁头哥哥" ;
execution.setVariable("name",name);]]>
</script>
</scriptTask>
<scriptTask id="printvars" name="输出变量" scriptFormat="groovy">
<script>
<![CDATA[out:println:name;]]>
</script>
</scriptTask>
JavaService Task允许定义一个实现指定接口的java类或者表达式,java类必须实现JavaDelegate,ActivityBehavior其中一个,还可以配置执行java类时所传入的变量
activiti:expression可以使用UEL定义需要执行的任务内容,例如计算公示,调用Bean的方法等
activiti:delegateExpression功能和activiti:class类似,而且同样需要实现JavaDelegate或ActivityBehavior中一个接口,只不过这里不是指定一个具体的实现类,而是运行的时候动态设置
<serviceTask id ="myServiceTask" name="Java Service" activiti:class="tietougege.activiti.JavaServiceDelegate">
</serviceTask>
<serviceTask id ="myService2" name="JavaService" activiti:expression="#{leaveService.back()}"/>
<serviceTask id ="myService3" name="JavaService" activiti:expression="${leaveServiceDelegate}"/>
通过Web Service任务可以调用外部的Web Service 资源,通过implementation="##WebService"可以定义task为webService类型,通过ioSpecification定义元素输入输出参数
dataInputAssociation定义了属性输入关系,dataOutputAssociation定义了属性输出关系
<serviceTask id="checkGeneralManagerAudit" name="是否需要总经理审批"
implementation="##WebService" operationRef="tns:auditOperation">
<ioSpecification>
<dataInput itemSubjectRef="tns:generalManagerAuditRequestItem"
id="dataInput" />
<dataOutput itemSubjectRef="tns:generalManagerAuditResponseItem"
id="dataOutput" />
<inputSet>
<dataInputRefs>dataInput</dataInputRefs>
</inputSet>
<outputSet>
<dataOutputRefs>dataOutput</dataOutputRefs>
</outputSet>
</ioSpecification>
<!-- 属性名称必须映射,否则报异常 https://gist.github.com/5994803 -->
<dataInputAssociation>
<sourceRef>startDate</sourceRef>
<targetRef>startDate</targetRef>
</dataInputAssociation>
<dataInputAssociation>
<sourceRef>endDate</sourceRef>
<targetRef>endDate</targetRef>
</dataInputAssociation>
<dataOutputAssociation>
<sourceRef>needed</sourceRef>
<targetRef>needed</targetRef>
</dataOutputAssociation>
</serviceTask>
网关
1.排他网关
2.并行网关
3.包容网关
4.事件网关
排他网关:流程执行到该网关时,按照输出流的顺序逐个计算,当条件计算结果为true时,继续执行当前网关的输出流,在排他网关中,如果多个网关的计算结果都为true,那么他只会执行第一个值为true的网关,忽略其他表达式为true的网关,如果多个网关没有为true的时,他会抛出异常
<excludsiveGateway id="exclusiveGateway" default="flow1"/>
<exclusiveGateway id="exclusivegateway5" name="Exclusive Gateway"></exclusiveGateway>
<sequenceFlow id="flow3" sourceRef="deptLeaderAudit"
targetRef="exclusivegateway5"></sequenceFlow>
<sequenceFlow id="flow4" name="拒绝" sourceRef="exclusivegateway5"
targetRef="modifyApply">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApproved == 'false'}]]></conditionExpression>
</sequenceFlow>
<sequenceFlow id="flow5" name="同意" sourceRef="exclusivegateway5"
targetRef="hrAudit">
<conditionExpression xsi:type="tFormalExpression"><![CDATA[${deptLeaderApproved == 'true'}]]></conditionExpression>
</sequenceFlow>
并行网关:对并发的任务进行流程建模,他能把单条线路任务拆分成多个路径并执行或将多条线路合并
<parallelGateway id="fork" name="Parallel GateWay Fork"></parallelGateway>
<userTask id ="usertask1" name="部门领导审批"></userTask>
<userTask id="usertask2" name="人事审批"></userTask>
<parallelGateway id="join" name="Parallel Gateway Join"></parallelGateway>
<userTask id="usertask3" name="考勤归档"></userTask>
<endEvent id="endEvent1" name="end"></endEvent>
<userTask id="usertask4" name="请假申请"></userTask>
<sequenceFlow id="flow2" name="" sourceRef="usertask4" targetRef="fork"/>
<sequenceFlow id="flow3" name="" sourceRef="fork" targetRef="usertask1"/>
<sequenceFlow id="flow4" name="" sourceRef="fork" targetRef="usertask2"/>
<sequenceFlow id="flow5" name="" sourceRef="usertask1" targetRef="join"/>
<sequenceFlow id="flow6" name="" sourceRef="usertask2" targetRef="join"/>
<sequenceFlow id="flow7" name="" sourceRef="join" targetRef="usertask3"/>
<sequenceFlow id="flow8" name="" sourceRef="usertask3" targetRef="endevent1"/>
<sequenceFlow id="flow9" name="" sourceRef="startevent1" targetRef="usertask4"/>
包容网关:包容网关融合了排他网关和并行网关的特性,排他网关允许在每条线路上设置条件,并行网关可以执行多条线路,包容网关既可以同时执行多条线路又可以在网关上设置条件
第一行定义了fork类型的包容网关,第二行定义了join类型的包容网关,第九行和第十四行是两个条件顺序流
1 <inclusiveGateway id="igFork" name="Inclusive Gateway fork"></inclusiveGateway>
2 <inlcusiveGateway id="igJoin" name="Inclusive GAteway Join"></inclusiveGateway>
3 <userTask id="usertask1" name="部门领导审批"></userTask>
4 <userTask id="usertask2" name="人事审批"></userTask>
5 <userTask id="usertask3" name="考勤归档"></userTask>
6 <endEvent id ="endEvent1" name="end" ></endEvent>
7 <userTask id="usertask4" name="请假申请"></userTask>
8 <sequenceFlow id="flow2" name="" sourceRef="usertask4" targetRef="igFork"/>
9 <sequenceFlow id="flow3" name="需要部门领导审批?" sourceRef="igFork" targetRef="usertask1"/>
10 <conditionExpression xsi:type="tFormalExpression">
11 <![CDATA[${leader==true}]]>
12 </conditionExpression>
13 <sequenceFlow>
14 <sequenceFlow id="flow4" name="需要人事审批?" sourceRef="igFork" targetRef="usertask2">
15 <conditionExpression xsi:type="tFormalExpression">
16 <![CDATA[${hr==true}]]>
17 </conditionExpression>
18 </sequenceFlow>
19 <sequenceFlow id="flow5" name="" sourceRef="usertask1" targetRef="igJoin"/>
20 <sequenceFlow id="flow6" name="" sourceRef="usertask2" targetRef="igJoin"/>
21 <sequenceFlow id="flow7" name="" sourceRef="igJoin" targetRef="usertask3"/>
22 <sequenceFlow id="flow8" name="" sourceRef="usertask3" targetRef="endevent1"/>
23 <sequenceFlow id ="flow9" name="" sourceRef="startevent" targetRef="usertask4"/>
事件网关:事件网关是专门为中间捕获事件设置的,它允许设置多个输出流指向多个不同的中间捕获事件(最少两个)。在流程执行到事件网关后,流程处于“等待”状态,因为中间捕获事件需要依赖中间抛出事件触发才能更改“等待”状态为“活动”状态,当然,定时捕获事件除外(他由时间驱动)
<signal id="alertSignal" name="alert"></signal>
<process id="EventGateway" name="EventGateway">
<startEvent id="startevent1" name="Start"></startEvent>
<eventBaseGateway id="eventgateway1" name="Event Gateway"></eventBaseGateway>
<intermediateCatchEvent id="timeintermediatecatchevent1" name="TimeCatchEvent">
<timeEventDefinition>
<timeDuration>PT1S</timeDuration>
</timeEventDefinition>
</intermediateCatchEvent>
<scriptTask id="scripttask1" name="定时器任务执行之后" scriptformat="groovy"><script><!CDATA[out:println "after time event";]]></script>
</scriptTask>
<intermediateCatchEvent id="signalintermediatecatcheevent1" name="SignalCatchEvent">
<signalEventDefinition signalRef="alertSignal">
</signalEventDefinition>
</intermediateCatchEvent>
<scriptTask id="scripttask2" name="信号捕获事件之后" scriptformat="groovy"><script><!CDATA[out:println "after signal event";]]></script></scriptTask>
<endEvent id="endEvent" name="END"></endEvent>
<sequenceFlow id="flow1" name="" soureRef="startevent1" targetRef="eventgateway1">
<sequenceFlow id="flow2" name="" soureRef="eventgateway1" targetRef="timeintermediatecatchevent1">
<sequenceFlow id="flow3" name="" soureRef="timeintermediatecatchevent1" targetRef="scripttask1">
<sequenceFlow id="flow4" name="" soureRef="eventgateway1" targetRef="signalintermediatecatcheevent1">
<sequenceFlow id="flow5" name="" soureRef="signalintermediatecatcheevent1" targetRef="scripttask2">
<sequenceFlow id="flow6" name="" soureRef="scripttask1" targetRef="endEvent">
<sequenceFlow id="flow7" name="" soureRef="scripttask2" targetRef="endEvent">
第一行定义一个信号等待中间信号捕获事件捕获,第五号定义了一个时间中间捕获事件,第12行定义了信号中间捕获事件,流程启动后两个输出流均处于等状态,等到中间捕获事件处理完成后变成活跃状态
子流程
在企业中还有一些通用的业务流程,例如,付款流程作为公司业务运作的核心流程之一,在业务设计和架构设计上会保持通用,或者在业务架构中作为一个通用的模块,不同的业务根据财务流程 的规范传入指定的参数就可以使用付款流程。
1.只能切仅能包含一个空启动流程
2.至少有一个结束流程
3.在子流程中顺序流不能直接设置输出流到子流程之外的活动中去,如果需要可以通过边界事件替代
<process id="subprocess" name="subprocess">
<startEvent id ="startevent1" name="start"></startEvent>
<userTask id ="usertask1" name="下单" ></userTask>
<endEvent id="end" name="end"></endEvent>
<subProcess id ="subprocess1" name="付款子流程">
<startEvent id="startEvent2" name="start"></startEvent>
<userTask id="usertask2" name="银行付款"></userTask>
<endEvent id ="endEvent1" name="End"></endEvent>
<serviceTask id="mailtask1" name="发送邮件" activiti:type="mail">
</serviceTask>
<sequenceFlow id="flow1" name="" sourceRef="startEvent2" targetRef="usertask2"></sequenceFlow>
<sequenceFlow id="flow2" name="" sourceRef="usertask2" targetRef="mailtask1"></sequenceFlow>
<sequenceFlow id="flow3" name="" sourceRef="mailtask1" targetRef="endEvent1"></sequenceFlow>
</subProcess>
<sequenceFlow id="flow4" name="" sourceRef="startevent1" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow5" name="" sourceRef="usertask1" targetRef="subprocess1"></sequenceFlow>
<sequenceFlow id="flow6" name="" sourceRef="subprocess1" targetRef="end"></sequenceFlow>
</process>
调用活动:调用活动解决的问题是流程的通用性,和子流程的作用一致,但是表现方式不同,使用一个调用活动却带嵌入子流程方式的活动即可,通过创建一个调用活动模型并指定外部流程的ID方式作为主流程的一个活动。
<callActivity id="callactivity1" name="调用付款流程" calledElement="payment">
<extensionElements>
<activiti: in source="amount" target="amount"></activiti:in>
<activiti:out source="paid" target="paid"></activiti:out>
<activiti:out sourceExpression="${payTime}" target="payTime"></activiti:out>
</extensionElements>
Activiti工作流学习笔记的更多相关文章
- Activiti工作流学习笔记(三)——自动生成28张数据库表的底层原理分析
原创/朱季谦 我接触工作流引擎Activiti已有两年之久,但一直都只限于熟悉其各类API的使用,对底层的实现,则存在较大的盲区. Activiti这个开源框架在设计上,其实存在不少值得学习和思考的地 ...
- Activiti工作流学习笔记(四)——工作流引擎中责任链模式的建立与应用原理
原创/朱季谦 本文需要一定责任链模式的基础,主要分成三部分讲解: 一.简单理解责任链模式概念 二.Activiti工作流里责任链模式的建立 三.Activiti工作流里责任链模式的应用 一.简单理解责 ...
- Activiti工作流学习笔记一
Activiti工作流 一:Activiti第一天 1:工作流的概念 说明: 假设:这两张图就是华谊兄弟的请假流程图 图的组成部分: 人物:范冰冰冯小刚王中军 事件(动作):请假.批准.不批准 工作流 ...
- Activiti工作流学习之流程图应用详解
Activiti工作流学习之流程图应用详解 1.目的 了解Activiti工作流是怎样应用流程图的. 2.环境准备2.1.相关软件及版本 jdk版本:Jdk1.7及以上 IDE:eclipse ...
- Activiti工作流学习之概述(一)
一.工作流介绍 我第一次听到这个词,是蒙逼的,再看百度百度,更傻眼了,完全说的不像人话啊,举几个生活中的例子,就明白多了比如:请假.报销等等,如果文字太过抽象,请看图: 二.工作流引擎 Process ...
- Activiti工作流学习(三)Activiti工作流与spring集成
一.前言 前面Activiti工作流的学习,说明了Activiti的基本应用,在我们开发中可以根据实际的业务参考Activiti的API去更好的理解以及巩固.我们实际的开发中我们基本上都使用sprin ...
- Activiti工作流学习(一)部署对象和流程定义
一.前言 前一段时间在工作中,使用了流程审批,对api的调用非常不熟悉,都是调用别人写好的接口在界面上进行显示,基本了解了流程审批的主要步骤,现对流程审批进行学习,主要是调用api进行CRUD操作,感 ...
- Activiti工作流学习-----基于5.19.0版本(6)
七. BPMN的简介 读者了解到这里,应付一般的工作流开发已经足够了.此处应该有华丽的分割线,在工作流项目中核心开发人员主要是对工作流业务设计以及实现,而初级开发人员是对业务功能的代码实现.以后将主要 ...
- Activiti工作流学习-----基于5.19.0版本(1)
该版本的Activiti运行须知: 1.JDK 6+,Eclipse最好是Kepler以上版本. 2.试验功能都有EXPERIMENTAL标注,被标注的部分不应该视为稳定的. 有兴趣的同学可以去了解下 ...
随机推荐
- windows docker redis
拉取docker docker pull hub.c.163.com/library/redis:latest 启动docker docker run -p 6379:6379 -d hub.c.16 ...
- HashMap源码分析(二)
前言:上篇文章,笔者分析了jdk1.7中HashMap的源码,这里将对jdk1.8的HashMap的源码进行分析. 注:jdk版本:jdk1.8.0_172 1.再看put操作 public V pu ...
- 老白关于rac性能调优的建议(10gRAC)
RAC应用设计方面需要在底层做很有设计.虽然ORACLE的售前人员总是说RAC的扩展性是透明的,只要把应用分到不同的节点,就可以平滑的扩展系统能力了.而事实上,RAC的CACHE FUSION机制决定 ...
- 003_python中key为中文的处理
由于统计域名资产信息时,部门名称是中文的,但是还需要用这个部门名称进行字符的匹配运算,但不进行转换处理的话,它会报以下的错误: 解决方法如下: # -*- coding: utf-8 -*- all_ ...
- ReSharper2018破解详细方法
下载地址: 主程序官网下载链接:https://download.jetbrains.com/resharper/ReSharperUltimate.2018.3.3/JetBrains.ReShar ...
- DotNetCore 3.0 助力 WPF 开发
DotNetCore Is AnyWhere. 前言 Visual Studio 2019 已经正式发布了,DotNetCore 3.0 的正式版也指日可待.在之前的版本中,作为一名基于微软生态的传统 ...
- 随心测试_软测基础_004<测试人员工作职责>
接上篇续,依据_软测基础体系:<依据不同的测试对象,选取适合的方法,按照设计的流程完成测试工作,检验整个过程是否达到测试的目的>.“学以致用”,实践于工作职责 常见面试题: —— 诸如以下 ...
- Facebook 广告投放相关概念简介(1)
本文不涉及具体代码实现,仅对开发API的前置内容做简单介绍,想参考代码请绕行! 广告主(广告管理工具) ·需要推广自己的应用.网站.主页,所以有了广告管理工具 . ·一个广告主仅可拥有一个广告账户(可 ...
- git错集
2018年12月20日22:26:01 fatal:not a git repository ( or any of the parent directories ) : .git 这个错误出现在首次 ...
- jmeter学习记录--04--Beanshell
一.什么是Bean Shell BeanShell是一种完全符合Java语法规范的脚本语言,并且又拥有自己的一些语法和方法;BeanShell是一种松散类型的脚本语言(这点和JS类似); BeanSh ...