摘要:本文通过一个工作流Activiti框架的具体使用示例,具体详尽的介绍了工作流Activiti框架的使用方式。

本文分享自华为云社区《一个使用示例,五个操作步骤!从此轻松掌握项目中工作流的开发》,作者:攻城狮Chova。

本文通过一个工作流Activiti框架的具体使用示例,具体详尽的介绍了工作流Activiti框架的使用方式。包括创建流程,发布流程,启动一个流程实例,完成一个流程实例以及挂起和激活一个流程实例。通过对工作流Activiti的具体使用步骤的掌握,基本上就能够学会了工作流Activiti的工作流程和具体使用。

创建流程

  • 要想操作Activiti引擎,需要通过org.activiti.engine.ProcessEngine实例暴露的服务.就可以操作一个org.activiti.engine.ProcessEngine
  • 创建一个请假申请的工作业务流程:

发布流程

  • 任何与“静态”资源有关的数据(比如流程定义)都可以通过RepositoryService访问,从概念上讲,所有静态数据都是Activiti的资源内容
  • src/test/resources/org/activiti/test目录下创建一个新的xml文件 VacationRequest.bpmn20.xml:
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <definitions id="definitions"
  3. targetNamespace="http://activiti.org/bpmn20"
  4. xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
  5. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  6. xmlns:activiti="http://activiti.org/bpmn">
  7.  
  8. <process id="vacationRequest" name="Vacation request">
  9.  
  10. <startEvent id="request" activiti:initiator="employeeName">
  11. <extensionElements>
  12. <activiti:formProperty id="numberOfDays" name="Number of days" type="long" value="1" required="true"/>
  13. <activiti:formProperty id="startDate" name="First day of holiday (dd-MM-yyy)" datePattern="dd-MM-yyyy hh:mm" type="date" required="true" />
  14. <activiti:formProperty id="vacationMotivation" name="Motivation" type="string" />
  15. </extensionElements>
  16. </startEvent>
  17. <sequenceFlow id="flow1" sourceRef="request" targetRef="handleRequest" />
  18.  
  19. <userTask id="handleRequest" name="Handle vacation request" >
  20. <documentation>
  21. ${employeeName} would like to take ${numberOfDays} day(s) of vacation (Motivation: ${vacationMotivation}).
  22. </documentation>
  23. <extensionElements>
  24. <activiti:formProperty id="vacationApproved" name="Do you approve this vacation" type="enum" required="true">
  25. <activiti:value id="true" name="Approve" />
  26. <activiti:value id="false" name="Reject" />
  27. </activiti:formProperty>
  28. <activiti:formProperty id="managerMotivation" name="Motivation" type="string" />
  29. </extensionElements>
  30. <potentialOwner>
  31. <resourceAssignmentExpression>
  32. <formalExpression>management</formalExpression>
  33. </resourceAssignmentExpression>
  34. </potentialOwner>
  35. </userTask>
  36. <sequenceFlow id="flow2" sourceRef="handleRequest" targetRef="requestApprovedDecision" />
  37.  
  38. <exclusiveGateway id="requestApprovedDecision" name="Request approved?" />
  39. <sequenceFlow id="flow3" sourceRef="requestApprovedDecision" targetRef="sendApprovalMail">
  40. <conditionExpression xsi:type="tFormalExpression">${vacationApproved == 'true'}</conditionExpression>
  41. </sequenceFlow>
  42.  
  43. <task id="sendApprovalMail" name="Send confirmation e-mail" />
  44. <sequenceFlow id="flow4" sourceRef="sendApprovalMail" targetRef="theEnd1" />
  45. <endEvent id="theEnd1" />
  46.  
  47. <sequenceFlow id="flow5" sourceRef="requestApprovedDecision" targetRef="adjustVacationRequestTask">
  48. <conditionExpression xsi:type="tFormalExpression">${vacationApproved == 'false'}</conditionExpression>
  49. </sequenceFlow>
  50.  
  51. <userTask id="adjustVacationRequestTask" name="Adjust vacation request">
  52. <documentation>
  53. Your manager has disapproved your vacation request for ${numberOfDays} days.
  54. Reason: ${managerMotivation}
  55. </documentation>
  56. <extensionElements>
  57. <activiti:formProperty id="numberOfDays" name="Number of days" value="${numberOfDays}" type="long" required="true"/>
  58. <activiti:formProperty id="startDate" name="First day of holiday (dd-MM-yyy)" value="${startDate}" datePattern="dd-MM-yyyy hh:mm" type="date" required="true" />
  59. <activiti:formProperty id="vacationMotivation" name="Motivation" value="${vacationMotivation}" type="string" />
  60. <activiti:formProperty id="resendRequest" name="Resend vacation request to manager?" type="enum" required="true">
  61. <activiti:value id="true" name="Yes" />
  62. <activiti:value id="false" name="No" />
  63. </activiti:formProperty>
  64. </extensionElements>
  65. <humanPerformer>
  66. <resourceAssignmentExpression>
  67. <formalExpression>${employeeName}</formalExpression>
  68. </resourceAssignmentExpression>
  69. </humanPerformer>
  70. </userTask>
  71. <sequenceFlow id="flow6" sourceRef="adjustVacationRequestTask" targetRef="resendRequestDecision" />
  72.  
  73. <exclusiveGateway id="resendRequestDecision" name="Resend request?" />
  74. <sequenceFlow id="flow7" sourceRef="resendRequestDecision" targetRef="handleRequest">
  75. <conditionExpression xsi:type="tFormalExpression">${resendRequest == 'true'}</conditionExpression>
  76. </sequenceFlow>
  77.  
  78. <sequenceFlow id="flow8" sourceRef="resendRequestDecision" targetRef="theEnd2">
  79. <conditionExpression xsi:type="tFormalExpression">${resendRequest == 'false'}</conditionExpression>
  80. </sequenceFlow>
  81. <endEvent id="theEnd2" />
  82.  
  83. </process>
  84.  
  85. </definitions>
  • 为了让Activiti引擎知道这个流程,我们必须先进行[发布],发布意味着引擎会把BPMN 2.0 xml解析成可以执行的东西,发布包中的所有流程定义都会添加到数据库中.这样,当引擎重启时,它依然可以获得[已发布]的流程:
  1. ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
  2. RepositoryService repositoryService = processEngine.getRepositoryService();
  3. repositoryService.createDeployment()
  4. .addClasspathResource("org/activiti/test/VacationRequest.bpmn20.xml")
  5. .deploy();
  6.  
  7. Log.info("Number of process definitions: " + repositoryService.createProcessDefinitionQuery().count());

启动一个流程实例

  • 把流程定义发布到Activiti引擎后,可以基于它发起新流程实例.
  • 对每个流程定义,都可以有很多流程实例.流程定义是"蓝图",流程实例是它的一个运行的执行
  • 所有与流程运行状态相关的东西都可以通过RuntimeService获得.有很多方法可以启动一个新流程实例.
    • 可以在流程实例启动时添加一些流程变量, 因为第一个用户任务的表达式需要这些变量.流程变量经常会被用到,因为它们赋予来自同一个流程定义的不同流程实例的特别含义
    • 流程变量是区分流程实例的关键
    • 下面使用定义在流程定义xml 中的key来启动流程实例:
  1. Map<String, Object> variables = new HashMap<String, Object>();
  2. variables.put("employeeName", "Kermit");
  3. variables.put("numberOfDays", new Integer(4));
  4. variables.put("vacationMotivation", "I'm really tired!");
  5.  
  6. RuntimeService runtimeService = processEngine.getRuntimeService();
  7. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("vacationRequest", variables);
  8.  
  9. // Verify that we started a new process instance
  10. Log.info("Number of process instances: " + runtimeService.createProcessInstanceQuery().count());

完成任务

  • 流程启动后,第一步就是用户任务.这是必须由系统用户处理的一个环节.
  • 用户会有一个"任务列表",展示了所有必须由整个用户处理的任务.下面是对应的查询:
    1. // Fetch all tasks for the management group
    2. TaskService taskService = processEngine.getTaskService();
    3. List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();
    4. for (Task task : tasks) {
    5. Log.info("Task available: " + task.getName());
    6. }

    为了让流程实例继续运行,我们**需要完成整个任务.**对Activiti来说,就是需要complete任务:

  1. Task task = tasks.get(0);
  2.  
  3. Map<String, Object> taskVariables = new HashMap<String, Object>();
  4. taskVariables.put("vacationApproved", "false");
  5. taskVariables.put("managerMotivation", "We have a tight deadline!");
  6. taskService.complete(task.getId(), taskVariables);
  • 然后流程实例就会进入到下一个环节
  • 下一环节允许员工通过表单调整原始的请假申请.员工可以重新提交请假申请,这会使流程重新进入到第一个任务

挂起或激活一个流程

  • 可以挂起一个流程定义,当挂起流程定义时,就不能创建新流程了,会抛出一个异常.可以通过RepositoryService挂起一个流程:
  1. repositoryService.suspendProcessDefinitionByKey("vacationRequest");
  2. try {
  3. runtimeService.startProcessInstanceByKey("vacationRequest");
  4. } catch (ActivitiException e) {
  5. e.printStackTrace();
  6. }
  • 要想重新激活一个流程定义,可以调用repositoryService.activateProcessDefinitionXXX方法
  • 也可以挂起一个流程实例:
    • 挂起时,流程不能继续执行:比如,完成任务会抛出异常,异步操作(比如定时器)也不会执行.挂起流程实例可以调用runtimeService.suspendProcessInstance方法
    • 激活流程实例可以调用runtimeService.activateProcessInstanceXXX方法

点击关注,第一时间了解华为云新鲜技术~

5步带你掌握工作流Activiti框架的使用的更多相关文章

  1. 工作流Activiti框架中表单的使用!详细解析内置表单和外置表单的渲染

    Activiti中的表单 Activiti提供了一种方便而且灵活的方式在业务流程中以手工方式添加表单 对表单的支持有2种方式: 通过表单属性对内置表单进行渲染 通过表单属性对外置表单进行渲染 表单属性 ...

  2. 工作流Activiti框架中的LDAP组件使用详解!实现对工作流目录信息的分布式访问及访问控制

    Activiti集成LDAP简介 企业在LDAP系统中保存了用户和群组信息,Activiti提供了一种解决方案,通过简单的配置就可以让activit连接LDAP 用法 要想在项目中集成LDAP,需要在 ...

  3. Activiti 框架学习

    1:工作流的概念 说明: 1)      假设:这两张图就是华谊兄弟的请假流程图 2)      图的组成部分: 人物:范冰冰 冯小刚 王中军 事件(动作):请假.批准.不批准 工作流(Workflo ...

  4. SSM整合activiti框架

    一:WorkFlow简介 1:什么是工作流工作流(Workflow),指“业务过程的部分或整体在计算机应用环境下的自动化”.是对工作流程及其各操作步骤之间业务规则的抽象.概括描述.在计算机中,工作流属 ...

  5. 工作流Activity框架入门(一)

    Activity工作流入门 1. 工作流概念 工作流(Workflow),就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某 ...

  6. 工作流,WEB框架,UI组件网络收集整理

    工作流,WEB框架,UI组件网络收集整理 在博客园上逛了好多年,随手收录了一些工作流,WEB开发框架,UI组件,现在整理一下与大家分享. 由于个人能力与精力有限,望各位园友在评论中补充,我将全部整理到 ...

  7. 工作流Activiti新手入门学习路线整理

    写在前面: 最近项目中使用到了工作流,虽然此部分不是自己需要完成的,但是也涉及到了要调用写的接口.正好有时间,就了解下,以便之后能在其他项目中用到时,不至于什么都不知道什么都不了解. 这里就主要整理下 ...

  8. 工作流引擎详解!工作流开源框架ACtiviti的详细配置以及安装和使用

    创建ProcessEngine Activiti流程引擎的配置文件是名为activiti.cfg.xml的XML文件.注意与使用Spring方式创建流程引擎是不一样的 使用org.activiti.e ...

  9. 工作流中的数据持久化详解!Activiti框架中JPA的使用分析

    Activiti中JPA简介 可以使用JPA实体作为流程变量, 并进行操作: 基于流程变量更新已有的JPA实体,可以在用户任务的表单中填写或者由服务任务生成 重用已有的领域模型,不需要编写显示的服务获 ...

  10. 工作流中的流程追溯!详细解析Activiti框架中的历史组件

    Activit中的历史简介 历史: Activiti中的一个组件,可以捕获发生在进程执行中的信息并永久的保存.与运行时数据不同的是,当流程实例运行完成之后它还会存在于数据库中 历史实体对象有5个: H ...

随机推荐

  1. Unity - UIWidgets 4. 添加图标显示

    Material Icon字体下载(github) 前面的返回按钮, 以及自己试验的一些Icon都不显示, 然后回去翻UIWidgets的README public class UIWidgetsEx ...

  2. HTML-9

    (一)常用方法 toFixed(); 四舍五入到小数点后几位 var x=9.656; x.toFixed(0);//10 x.toFixed(2);//9.66 x.toFixed(4);//9.6 ...

  3. 学习Hadoop不错的系列文章(转)

    http://www.cnblogs.com/xia520pi/archive/2012/04/22/2464934.html 1)Hadoop学习总结 (1)HDFS简介 地址:http://for ...

  4. JUC并发编程学习笔记(六)Callable(简单)

    Callable(简单) callable接口和runnable接口类似,都是为了执行另外一条线程而设计的,区别是Runnable不会返回结果也不会抛出异常. 1.可以有返回值 2.可以抛出异常 3. ...

  5. 《最新出炉》系列初窥篇-Python+Playwright自动化测试-32-JavaScript的调用执行-下篇

    1.简介 在实际工作中,我们需要对处理的元素进行高亮显示,或者有时候为了看清楚操作过程和步骤我们需要跟踪鼠标点击了哪些元素需要标记出来.虽然很少遇到,但是为了以后大家可以参考或者提供一种思路,今天宏哥 ...

  6. 运行tomcat之后报一个:"Address localhost:1099 is already in use"错误

    一.解决方案 1.错误原因 "地址 localhost:1099 已在使用中",是1099程序被占用,把1099程序后台停止掉即可. 2.解决方案 1.快捷键win+R打开CMD运 ...

  7. RabbitMQ高可用集群的搭建部署(Centos7)

    高可用集群架构 节点域名 操作系统 RabbitMQ版本 Erlang版本 iamdemo.tp-link.com Centos7.9 3.8.28 23.3-2 iamdemo2.tp-link.c ...

  8. 数据库系列:MySQL不同操作分别用什么锁?

    数据库系列:MySQL慢查询分析和性能优化 数据库系列:MySQL索引优化总结(综合版) 数据库系列:高并发下的数据字段变更 数据库系列:覆盖索引和规避回表 数据库系列:数据库高可用及无损扩容 数据库 ...

  9. SpringCore 完整学习教程1,入门级别

    1. SpringApplication SpringApplication类提供了一种方便的方式来引导从main()方法启动的Spring应用程序.在很多情况下,你可以委托给静态的SpringApp ...

  10. 吉特日化MES & 标签的设计与选择

    吉特日化MES & 标签的设计与选择:如今条码和二维码在生活中随处可见,作为一种能够快速精准读取识别的手段,条码和二维码在生产车间也应用的较为广泛.如果说条码和二维码哪一种更好,我更加倾向于使 ...