1 个人任务

1.1 分配任务负责人

1.1.1 固定分配

  • 在进行业务流程建模的时候指定固定的任务负责人。

固定分配.png

  • 在properties视图中,添加Assignee项为任务负责人。

由于固定分配方式,任务只管一步一步执行任务,执行到每一个任务将按照BPMN的配置去分配任务负责人。

1.1.2 表达式分配

1.1.2.1 UEL表达式

  • Activiti使用UEL表达式,UEL是JavaEE规范的一部分,URL(Unified Expression Language)即统一表达式语言,Activiti支持两种UEL表达式:UEL-value和UEL-method。
  • UEL-value定义如下:
    • assignee这个变量是Activiti的一个流程变量。

UEL-value.png

  • user这个变量也是Activiti的一个流程变量,user.assignee表示通过调用user的getter方法获取值。

另外一种UEL-value.png

  • UEL-method定义如下:
    • holidayBean是Spring容器中的一个Bean,下图UEL-method的含义是调用该Bean的一个getHolidayId()方法。

UEL-method.png

1.1.2.2 使用流程变量分配任务

  • 定义任务分配流程变量:

UEL-value.png

  • 设置流程变量:在启动流程实例的时候设置流程变量
  1. package com.sunxiaping;
  2. import org.activiti.engine.ProcessEngine;
  3. import org.activiti.engine.ProcessEngineConfiguration;
  4. import org.activiti.engine.RuntimeService;
  5. import org.activiti.engine.runtime.ProcessInstance;
  6. import org.junit.Test;
  7. import java.util.HashMap;
  8. import java.util.Map;
  9. /**
  10. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  11. * @version 1.0
  12. * 2020-08-01 14:35
  13. */
  14. public class ActivitiStartProcessInstanceTest {
  15. /**
  16. * act_hi_actinst 活动实例
  17. * act_hi_identitylink 参与者信息
  18. * act_hi_procinst 流程实例
  19. * act_hi_taskinst 任务实例
  20. * act_ru_execution 执行表
  21. * act_ru_identitylink 参与者信息
  22. * act_ru_task 任务表
  23. */
  24. @Test
  25. public void test() {
  26. //创建ProcessEngineConfiguration对象
  27. ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
  28. ProcessEngine processEngine = configuration.buildProcessEngine();
  29. //获取RuntimeService对象
  30. RuntimeService runtimeService = processEngine.getRuntimeService();
  31. //设置流程变量
  32. Map<String, Object> variables = new HashMap<>();
  33. variables.put("assignee0", "张三");
  34. variables.put("assignee1", "李四");
  35. variables.put("assignee2", "王五");
  36. //根据流程定义的key启动流程实例
  37. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday", variables);
  38. //获取流程实例的相关信息
  39. String processDefinitionId = processInstance.getProcessDefinitionId();
  40. System.out.println("流程定义的id = " + processDefinitionId);
  41. String deploymentId = processInstance.getDeploymentId();
  42. System.out.println("流程部署的id = " + deploymentId);
  43. String id = processInstance.getId();
  44. System.out.println("流程实例的id = " + id);
  45. String activityId = processInstance.getActivityId();
  46. System.out.println("当前活动的id = " + activityId);
  47. }
  48. }

1.1.2.3 注意事项

  • 由于使用了表达式分配,必须保证在任务执行过程中表达式执行成功,比如某个任务使用了表达式${order.price > 100 && order.price <250},当执行该任务时必须保证order在流程变量中存在,否则Activiti将抛出异常。

1.1.3 监听器分配

  • 任务监听器是发生对应的任务相关事件时执行自定义的Java逻辑或表达式。
  • 任务相关事件包括:
    • Event:
      • Create:任务创建后触发。
      • Assignment:任务分配后触发。
      • Delete:任务完成后触发。
      • All:所有事件发生都触发。

监听器分配.png

  • 自定义一个任务监听器类,然后此类必须实现org.activiti.engine.delegate.TaskListener接口:
  1. package com.sunxiaping.task;
  2. import org.activiti.engine.delegate.DelegateTask;
  3. import org.activiti.engine.delegate.TaskListener;
  4. /**
  5. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  6. * @version 1.0
  7. * 2020-08-05 15:44
  8. */
  9. public class SelfTaskListener implements TaskListener {
  10. @Override
  11. public void notify(DelegateTask delegateTask) {
  12. //指定任务的负责人
  13. delegateTask.setAssignee("张三");
  14. }
  15. }

在实际开发中,一般也不使用监听器分配方式,太麻烦了。

2 流程变量

2.1 什么是流程变量?

  • 流程变量在Activiti中是一个非常重要的角色,流程运转有时需要靠流程变量,业务系统和Activiti结合时少不了流程变量,流程变量就是Activiti在管理工作流时根据管理需要而设置的变量。
  • 比如在请假流程流转时如果请假天数>3天则有总经理审批,否则由人事直接审批,请假天数就可以设置流程变量,在流程流转时使用。

注意:虽然流程变量中可以存储业务数据,可以通过Activiti的API查询流程变量从而实现查询业务数据,但是不建议这么使用,因为业务数据查询由业务系统负责,Activiti设置流程变量是为了流程执行需要而创建的。

2.2 流程变量类型

流程变量类型.png

注意:

  • 如果将POJO存储到流程变量中,必须实现序列化接口Serializable,为了防止由于新增字段无法反序列化。

2.3 流程变量的作用域

  • 流程变量的作用域范围可以是一个流程实例(ProcessInstance)、一个任务(Task)或一个执行实例(Execution)。
  • 流程变量的作用域范围的默认值是流程实例,作用域范围最大,可以称为global变量。
  • 流程变量的作用域范围如果仅仅针对一个任务或一个执行实例,那么作用域范围没有流程实例大,可以称为local变量。
  • global变量中变量名不允许重复,设置相同名称的变量,后设置的值会覆盖前设置的变量值。
  • local变量由于在不同的任务或不同的执行实例中,作用域互不影响,变量名可以相同没有影响。local变量名也可以和global变量名相同,没有影响。

2.4 流程变量的使用方法

  • ①设置流程变量。
  • ②通过UEL表达式使用流程变量。
    • Activiti7进阶之个人任务和流程变量 - 图8可以在assignee处设置UEL表达式,表达值的值就是任务的负责人。例如:${assignee},assignee就是一个流程变量的名称。

在assignee处设置UEL表达式.png

  • Activiti7进阶之个人任务和流程变量 - 图10可以在连线上设置UEL表达式,决定流程的走向。例如:${holidayNum>=3}${holidayNum<3}中holidayNum就是一个流程变量名称,UEL表达式的结果类型为boolean类型,如果UEL表达式的值是true,则总经理审批,否则直接人事存档。

在连线上设置UEL表达式.png

2.5 使用global变量控制流程

2.5.1 需求

  • 员工创建请假流程申请单,由部门经理审批,部门经理审批通过后请假3天以下的由人事经理直接审批,3天及3天以上的由总经理审批,总经理审批通过再通过人事经理存档。

使用global变量控制流程的需求.png

2.5.2 画流程定义

  • 请假大于等于3天的连线条件:

请假大于等于3天的连线条件.png

  • 请假小于3天的连线条件:

请假小于3天的连线条件.png

本人在画BPMN文件的时候将填写请假申请单的assignee设置为张三,部门经理审批的assignee设置为李四,总经理审批的assignee设置为王五,人事经理存档设置为赵六。

2.5.3 设置global流程变量

2.5.3.1 准备工作

  • 导入相关jar包的Maven坐标:
  1. <properties>
  2. <activiti.version>7.0.0.GA</activiti.version>
  3. </properties>
  4. <dependencies>
  5. <dependency>
  6. <groupId>org.activiti</groupId>
  7. <artifactId>activiti-engine</artifactId>
  8. <version>7.0.0.GA</version>
  9. </dependency>
  10. <dependency>
  11. <groupId>org.activiti</groupId>
  12. <artifactId>activiti-spring</artifactId>
  13. <version>${activiti.version}</version>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.activiti</groupId>
  17. <artifactId>activiti-bpmn-model</artifactId>
  18. <version>${activiti.version}</version>
  19. </dependency>
  20. <dependency>
  21. <groupId>org.activiti</groupId>
  22. <artifactId>activiti-bpmn-converter</artifactId>
  23. <version>${activiti.version}</version>
  24. </dependency>
  25. <dependency>
  26. <groupId>org.activiti</groupId>
  27. <artifactId>activiti-json-converter</artifactId>
  28. <version>${activiti.version}</version>
  29. </dependency>
  30. <dependency>
  31. <groupId>org.activiti</groupId>
  32. <artifactId>activiti-bpmn-layout</artifactId>
  33. <version>${activiti.version}</version>
  34. </dependency>
  35. <dependency>
  36. <groupId>org.activiti.cloud</groupId>
  37. <artifactId>activiti-cloud-services-api</artifactId>
  38. <version>7-201802-EA</version>
  39. </dependency>
  40. <dependency>
  41. <groupId>mysql</groupId>
  42. <artifactId>mysql-connector-java</artifactId>
  43. <version>8.0.19</version>
  44. </dependency>
  45. <dependency>
  46. <groupId>junit</groupId>
  47. <artifactId>junit</artifactId>
  48. <version>4.12</version>
  49. </dependency>
  50. <!-- log start -->
  51. <dependency>
  52. <groupId>org.apache.logging.log4j</groupId>
  53. <artifactId>log4j-core</artifactId>
  54. <version>2.13.3</version>
  55. </dependency>
  56. <dependency>
  57. <groupId>org.apache.logging.log4j</groupId>
  58. <artifactId>log4j-api</artifactId>
  59. <version>2.13.3</version>
  60. </dependency>
  61. <dependency>
  62. <groupId>org.slf4j</groupId>
  63. <artifactId>slf4j-api</artifactId>
  64. <version>1.7.30</version>
  65. </dependency>
  66. <dependency>
  67. <groupId>org.apache.logging.log4j</groupId>
  68. <artifactId>log4j-slf4j-impl</artifactId>
  69. <version>2.13.3</version>
  70. </dependency>
  71. <!-- log end -->
  72. <dependency>
  73. <groupId>org.mybatis</groupId>
  74. <artifactId>mybatis</artifactId>
  75. <version>3.4.5</version>
  76. </dependency>
  77. <dependency>
  78. <groupId>commons-dbcp</groupId>
  79. <artifactId>commons-dbcp</artifactId>
  80. <version>1.4</version>
  81. </dependency>
  82. </dependencies>
  83. <dependencyManagement>
  84. <dependencies>
  85. <dependency>
  86. <groupId>org.activiti.cloud.dependencies</groupId>
  87. <artifactId>activiti-cloud-dependencies</artifactId>
  88. <version>7.0.0.GA</version>
  89. <scope>import</scope>
  90. <type>pom</type>
  91. </dependency>
  92. </dependencies>
  93. </dependencyManagement>
  • 日志文件(log4j2.xml)
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL -->
  3. <!--Configuration后面的status用于设置log4j2自身内部的信息输出,可以不设置,当设置成trace时,可以看到log4j2内部各种详细输出-->
  4. <configuration status="INFO">
  5. <!--先定义所有的appender-->
  6. <appenders>
  7. <!--输出日志信息到控制台-->
  8. <console name="Console" target="SYSTEM_OUT">
  9. <!--控制日志输出的格式-->
  10. <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
  11. </console>
  12. </appenders>
  13. <!--然后定义logger,只有定义了logger并引入的appender,appender才会生效-->
  14. <!--root:用于指定项目的根日志,如果没有单独指定Logger,则会使用root作为默认的日志输出-->
  15. <loggers>
  16. <root level="INFO">
  17. <appender-ref ref="Console"/>
  18. </root>
  19. </loggers>
  20. </configuration>
  • Activiti的核心配置文件(activiti-cfg.xml)
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:context="http://www.springframework.org/schema/context"
  4. xmlns="http://www.springframework.org/schema/beans"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/context
  8. http://www.springframework.org/schema/context/spring-context.xsd">
  9. <!-- 配置数据源 -->
  10. <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
  11. <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
  12. <property name="username" value="root"/>
  13. <property name="url"
  14. value="jdbc:mysql://192.168.1.146:3306/activiti?useUnicode=true&amp;characterEncoding=UTF-8&amp;autoReconnect=true&amp;useSSL=false&amp;serverTimezone=GMT%2B8&amp;allowPublicKeyRetrieval=true"/>
  15. <property name="password" value="123456"/>
  16. <property name="maxActive" value="3"/>
  17. <property name="maxIdle" value="1"/>
  18. </bean>
  19. <!-- Activiti单独运行的ProcessEngine配置 -->
  20. <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
  21. <!-- 数据源 -->
  22. <property name="dataSource" ref="dataSource"/>
  23. <!--
  24. activiti数据库表处理策略
  25. false(默认值):检查数据库的版本和依赖库的版本,如果不匹配就抛出异常
  26. true:构建流程引擎时,执行检查,如果需要就执行更新。如果表不存在,就创建。
  27. create-drop:构建流程引擎时创建数据库报表,关闭流程引擎时就删除这些表。
  28. drop-create:先删除表再创建表。
  29. create:构建流程引擎时创建数据库表,关闭流程引擎时不删除这些表
  30. -->
  31. <property name="databaseSchemaUpdate" value="true"/>
  32. </bean>
  33. </beans>
  • 请假实体类(Holiday.java)
  1. package com.sunxiaping.task;
  2. import java.io.Serializable;
  3. import java.util.Date;
  4. /**
  5. * 请假实体类
  6. *
  7. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  8. * @version 1.0
  9. * 2020-08-06 14:30
  10. */
  11. public class Holiday implements Serializable {
  12. /**
  13. * 主键
  14. */
  15. private Integer id;
  16. /**
  17. * 申请人名字
  18. */
  19. private String holidayName;
  20. /**
  21. * 开始时间
  22. */
  23. private Date beginDate;
  24. /**
  25. * 结束时间
  26. */
  27. private Date endDate;
  28. /**
  29. * 请假天数
  30. */
  31. private Float num;
  32. /**
  33. * 请假事由
  34. */
  35. private String reason;
  36. /**
  37. * 请假类型:病假、婚假、丧假等
  38. */
  39. private String type;
  40. public Integer getId() {
  41. return id;
  42. }
  43. public void setId(Integer id) {
  44. this.id = id;
  45. }
  46. public String getHolidayName() {
  47. return holidayName;
  48. }
  49. public void setHolidayName(String holidayName) {
  50. this.holidayName = holidayName;
  51. }
  52. public Date getBeginDate() {
  53. return beginDate;
  54. }
  55. public void setBeginDate(Date beginDate) {
  56. this.beginDate = beginDate;
  57. }
  58. public Date getEndDate() {
  59. return endDate;
  60. }
  61. public void setEndDate(Date endDate) {
  62. this.endDate = endDate;
  63. }
  64. public Float getNum() {
  65. return num;
  66. }
  67. public void setNum(Float num) {
  68. this.num = num;
  69. }
  70. public String getReason() {
  71. return reason;
  72. }
  73. public void setReason(String reason) {
  74. this.reason = reason;
  75. }
  76. public String getType() {
  77. return type;
  78. }
  79. public void setType(String type) {
  80. this.type = type;
  81. }
  82. }
  • 将流程定义和对应的图片放入到resources目录下:

在classpath下放入流程定义文件和图片.png

2.5.3.2 启动流程时设置

  • 示例:
  1. package com.sunxiaping.test;
  2. import com.sunxiaping.task.Holiday;
  3. import org.activiti.engine.*;
  4. import org.activiti.engine.repository.Deployment;
  5. import org.activiti.engine.runtime.ProcessInstance;
  6. import org.activiti.engine.task.Task;
  7. import org.junit.After;
  8. import org.junit.Before;
  9. import org.junit.Test;
  10. import java.time.LocalDateTime;
  11. import java.time.ZoneId;
  12. import java.util.Date;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * global流程变量测试:启动流程时设置
  18. *
  19. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  20. * @version 1.0
  21. * 2020-08-06 14:28
  22. */
  23. public class ActivitiGlobalVariableStartProcessInstanceTest {
  24. ProcessEngine processEngine = null;
  25. @Before
  26. public void before() {
  27. ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
  28. processEngine = configuration.buildProcessEngine();
  29. }
  30. @After
  31. public void after() {
  32. if (processEngine != null) {
  33. processEngine.close();
  34. }
  35. }
  36. /**
  37. * 流程定义部署
  38. */
  39. @Test
  40. public void testDeployment() {
  41. //获取RepositoryService对象
  42. RepositoryService repositoryService = processEngine.getRepositoryService();
  43. //获取Deployment对象
  44. Deployment deployment = repositoryService.createDeployment()
  45. .addClasspathResource("diagram/holiday.bpmn")
  46. .addClasspathResource("diagram/holiday.png")
  47. .name("请假申请流程")
  48. .deploy();
  49. String id = deployment.getId();
  50. System.out.println("流程部署的id = " + id);
  51. String name = deployment.getName();
  52. System.out.println("流程部署的名称 = " + name);
  53. String key = deployment.getKey();
  54. System.out.println("流程部署的key = " + key);
  55. }
  56. /**
  57. * 启动流程的时候给流程变量赋值
  58. */
  59. @Test
  60. public void testStartProcessInstance() {
  61. //流程定义的key
  62. String processDefinitionKey = "holiday";
  63. //获取RuntimeService对象
  64. RuntimeService runtimeService = processEngine.getRuntimeService();
  65. //封装global流程变量
  66. Holiday holiday = new Holiday();
  67. holiday.setNum(3f);
  68. holiday.setHolidayName("如花");
  69. holiday.setId(1);
  70. holiday.setType("年假");
  71. holiday.setReason("想男友了");
  72. holiday.setBeginDate(new Date());
  73. LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
  74. Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
  75. holiday.setEndDate(endDate);
  76. Map<String, Object> variables = new HashMap<>();
  77. variables.put("holiday", holiday);
  78. //根据流程定义的key启动流程实例
  79. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
  80. String id = processInstance.getId();
  81. System.out.println("流程实例的id = " + id);
  82. String name = processInstance.getName();
  83. System.out.println("流程实例的名称 = " + name);
  84. String processDefinitionId = processInstance.getProcessDefinitionId();
  85. System.out.println("流程定义的id = " + processDefinitionId);
  86. }
  87. /**
  88. * 测试张三完成任务
  89. */
  90. @Test
  91. public void testZhangSanTask() {
  92. String assignee = "张三";
  93. //流程定义的key
  94. String processDefinitionKey = "holiday";
  95. //获取TaskService对象
  96. TaskService taskService = processEngine.getTaskService();
  97. //获取张三任务的列表
  98. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  99. for (Task task : taskList) {
  100. //任务的id
  101. String id = task.getId();
  102. System.out.println("张三任务的id = " + id);
  103. taskService.complete(id);
  104. }
  105. }
  106. /**
  107. * 测试李四完成任务
  108. */
  109. @Test
  110. public void testLiSiTask() {
  111. String assignee = "李四";
  112. //流程定义的key
  113. String processDefinitionKey = "holiday";
  114. //获取TaskService对象
  115. TaskService taskService = processEngine.getTaskService();
  116. //获取李四任务的列表
  117. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  118. for (Task task : taskList) {
  119. //任务的id
  120. String id = task.getId();
  121. System.out.println("李四任务的id = " + id);
  122. taskService.complete(id);
  123. }
  124. }
  125. /**
  126. * 测试王五和赵六的任务,查看到底是王五还是赵六有任务
  127. */
  128. @Test
  129. public void testWangWuTask() {
  130. String assignee = "王五";
  131. //流程定义的key
  132. String processDefinitionKey = "holiday";
  133. //获取TaskService对象
  134. TaskService taskService = processEngine.getTaskService();
  135. //获取王五任务的列表
  136. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  137. for (Task task : taskList) {
  138. //任务的id
  139. String id = task.getId();
  140. System.out.println("王五任务的id = " + id);
  141. }
  142. assignee = "赵六";
  143. taskService = processEngine.getTaskService();
  144. //获取赵六任务的列表
  145. taskList = taskService.createTaskQuery().taskAssignee(assignee).list();
  146. for (Task task : taskList) {
  147. //任务的id
  148. String id = task.getId();
  149. System.out.println("赵六任务的id = " + id);
  150. }
  151. }
  152. }

2.5.3.3 完成任务时设置

  • 示例:
  1. package com.sunxiaping.test;
  2. import com.sunxiaping.task.Holiday;
  3. import org.activiti.engine.*;
  4. import org.activiti.engine.repository.Deployment;
  5. import org.activiti.engine.runtime.ProcessInstance;
  6. import org.activiti.engine.task.Task;
  7. import org.junit.After;
  8. import org.junit.Before;
  9. import org.junit.Test;
  10. import java.time.LocalDateTime;
  11. import java.time.ZoneId;
  12. import java.util.Date;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * global流程变量测试:完成任务时设置
  18. *
  19. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  20. * @version 1.0
  21. * 2020-08-06 14:28
  22. */
  23. public class ActivitiGlobalVariableCompleteTaskTest {
  24. ProcessEngine processEngine = null;
  25. @Before
  26. public void before() {
  27. ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
  28. processEngine = configuration.buildProcessEngine();
  29. }
  30. @After
  31. public void after() {
  32. if (processEngine != null) {
  33. processEngine.close();
  34. }
  35. }
  36. /**
  37. * 流程定义部署
  38. */
  39. @Test
  40. public void testDeployment() {
  41. //获取RepositoryService对象
  42. RepositoryService repositoryService = processEngine.getRepositoryService();
  43. //获取Deployment对象
  44. Deployment deployment = repositoryService.createDeployment()
  45. .addClasspathResource("diagram/holiday.bpmn")
  46. .addClasspathResource("diagram/holiday.png")
  47. .name("请假申请流程")
  48. .deploy();
  49. String id = deployment.getId();
  50. System.out.println("流程部署的id = " + id);
  51. String name = deployment.getName();
  52. System.out.println("流程部署的名称 = " + name);
  53. String key = deployment.getKey();
  54. System.out.println("流程部署的key = " + key);
  55. }
  56. /**
  57. * 启动流程
  58. */
  59. @Test
  60. public void testStartProcessInstance() {
  61. //流程定义的key
  62. String processDefinitionKey = "holiday";
  63. //获取RuntimeService对象
  64. RuntimeService runtimeService = processEngine.getRuntimeService();
  65. //根据流程定义的key启动流程实例
  66. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
  67. String id = processInstance.getId();
  68. System.out.println("流程实例的id = " + id);
  69. String name = processInstance.getName();
  70. System.out.println("流程实例的名称 = " + name);
  71. String processDefinitionId = processInstance.getProcessDefinitionId();
  72. System.out.println("流程定义的id = " + processDefinitionId);
  73. }
  74. /**
  75. * 测试张三完成任务,张三完成任务的时候给global变量赋值
  76. */
  77. @Test
  78. public void testZhangSanTask() {
  79. String assignee = "张三";
  80. //流程定义的key
  81. String processDefinitionKey = "holiday";
  82. //获取TaskService对象
  83. TaskService taskService = processEngine.getTaskService();
  84. //获取张三任务的列表
  85. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  86. for (Task task : taskList) {
  87. //任务的id
  88. String id = task.getId();
  89. System.out.println("张三任务的id = " + id);
  90. //封装global流程变量
  91. Holiday holiday = new Holiday();
  92. holiday.setNum(3f);
  93. holiday.setHolidayName("如花");
  94. holiday.setId(1);
  95. holiday.setType("年假");
  96. holiday.setReason("想男友了");
  97. holiday.setBeginDate(new Date());
  98. LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
  99. Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
  100. holiday.setEndDate(endDate);
  101. Map<String, Object> variables = new HashMap<>();
  102. variables.put("holiday", holiday);
  103. taskService.complete(id, variables);
  104. }
  105. }
  106. /**
  107. * 测试李四完成任务
  108. */
  109. @Test
  110. public void testLiSiTask() {
  111. String assignee = "李四";
  112. //流程定义的key
  113. String processDefinitionKey = "holiday";
  114. //获取TaskService对象
  115. TaskService taskService = processEngine.getTaskService();
  116. //获取李四任务的列表
  117. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  118. for (Task task : taskList) {
  119. //任务的id
  120. String id = task.getId();
  121. System.out.println("李四任务的id = " + id);
  122. taskService.complete(id);
  123. }
  124. }
  125. /**
  126. * 测试王五和赵六的任务,查看到底是王五还是赵六有任务
  127. */
  128. @Test
  129. public void testWangWuTask() {
  130. String assignee = "王五";
  131. //流程定义的key
  132. String processDefinitionKey = "holiday";
  133. //获取TaskService对象
  134. TaskService taskService = processEngine.getTaskService();
  135. //获取王五任务的列表
  136. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  137. for (Task task : taskList) {
  138. //任务的id
  139. String id = task.getId();
  140. System.out.println("王五任务的id = " + id);
  141. }
  142. assignee = "赵六";
  143. taskService = processEngine.getTaskService();
  144. //获取赵六任务的列表
  145. taskList = taskService.createTaskQuery().taskAssignee(assignee).list();
  146. for (Task task : taskList) {
  147. //任务的id
  148. String id = task.getId();
  149. System.out.println("赵六任务的id = " + id);
  150. }
  151. }
  152. }

2.5.3.4 通过当前流程实例设置

  • 通过流程实例的id设置全局流程变量,该流程实例必须没有执行完毕。
  • 示例:
  1. package com.sunxiaping.test;
  2. import com.sunxiaping.task.Holiday;
  3. import org.activiti.engine.*;
  4. import org.activiti.engine.repository.Deployment;
  5. import org.activiti.engine.runtime.ProcessInstance;
  6. import org.activiti.engine.task.Task;
  7. import org.junit.After;
  8. import org.junit.Before;
  9. import org.junit.Test;
  10. import java.time.LocalDateTime;
  11. import java.time.ZoneId;
  12. import java.util.Date;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * global流程变量测试:通过当前流程实例设置
  18. *
  19. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  20. * @version 1.0
  21. * 2020-08-06 14:28
  22. */
  23. public class ActivitiGlobalVariableCurrentExecutionIdTest {
  24. ProcessEngine processEngine = null;
  25. @Before
  26. public void before() {
  27. ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
  28. processEngine = configuration.buildProcessEngine();
  29. }
  30. @After
  31. public void after() {
  32. if (processEngine != null) {
  33. processEngine.close();
  34. }
  35. }
  36. /**
  37. * 流程定义部署
  38. */
  39. @Test
  40. public void testDeployment() {
  41. //获取RepositoryService对象
  42. RepositoryService repositoryService = processEngine.getRepositoryService();
  43. //获取Deployment对象
  44. Deployment deployment = repositoryService.createDeployment()
  45. .addClasspathResource("diagram/holiday.bpmn")
  46. .addClasspathResource("diagram/holiday.png")
  47. .name("请假申请流程")
  48. .deploy();
  49. String id = deployment.getId();
  50. System.out.println("流程部署的id = " + id);
  51. String name = deployment.getName();
  52. System.out.println("流程部署的名称 = " + name);
  53. String key = deployment.getKey();
  54. System.out.println("流程部署的key = " + key);
  55. }
  56. /**
  57. * 启动流程
  58. */
  59. @Test
  60. public void testStartProcessInstance() {
  61. //流程定义的key
  62. String processDefinitionKey = "holiday";
  63. //获取RuntimeService对象
  64. RuntimeService runtimeService = processEngine.getRuntimeService();
  65. //根据流程定义的key启动流程实例
  66. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
  67. String id = processInstance.getId();
  68. System.out.println("流程实例的id = " + id);
  69. String name = processInstance.getName();
  70. System.out.println("流程实例的名称 = " + name);
  71. String processDefinitionId = processInstance.getProcessDefinitionId();
  72. System.out.println("流程定义的id = " + processDefinitionId);
  73. }
  74. /**
  75. * 通过流程实例的id设置流程变量,该流程必须没有执行完毕
  76. */
  77. @Test
  78. public void testSetVariable(){
  79. String executionId = "2501";
  80. //封装global流程变量
  81. Holiday holiday = new Holiday();
  82. holiday.setNum(3f);
  83. holiday.setHolidayName("如花");
  84. holiday.setId(1);
  85. holiday.setType("年假");
  86. holiday.setReason("想男友了");
  87. holiday.setBeginDate(new Date());
  88. LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
  89. Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
  90. holiday.setEndDate(endDate);
  91. Map<String, Object> variables = new HashMap<>();
  92. variables.put("holiday", holiday);
  93. //获取RuntimeService对象
  94. RuntimeService runtimeService = processEngine.getRuntimeService();
  95. //设置流程变量
  96. runtimeService.setVariables(executionId,variables);
  97. }
  98. /**
  99. * 测试张三完成任务
  100. */
  101. @Test
  102. public void testZhangSanTask() {
  103. String assignee = "张三";
  104. //流程定义的key
  105. String processDefinitionKey = "holiday";
  106. //获取TaskService对象
  107. TaskService taskService = processEngine.getTaskService();
  108. //获取张三任务的列表
  109. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  110. for (Task task : taskList) {
  111. //任务的id
  112. String id = task.getId();
  113. System.out.println("张三任务的id = " + id);
  114. taskService.complete(id);
  115. }
  116. }
  117. /**
  118. * 测试李四完成任务
  119. */
  120. @Test
  121. public void testLiSiTask() {
  122. String assignee = "李四";
  123. //流程定义的key
  124. String processDefinitionKey = "holiday";
  125. //获取TaskService对象
  126. TaskService taskService = processEngine.getTaskService();
  127. //获取李四任务的列表
  128. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  129. for (Task task : taskList) {
  130. //任务的id
  131. String id = task.getId();
  132. System.out.println("李四任务的id = " + id);
  133. taskService.complete(id);
  134. }
  135. }
  136. /**
  137. * 测试王五和赵六的任务,查看到底是王五还是赵六有任务
  138. */
  139. @Test
  140. public void testWangWuTask() {
  141. String assignee = "王五";
  142. //流程定义的key
  143. String processDefinitionKey = "holiday";
  144. //获取TaskService对象
  145. TaskService taskService = processEngine.getTaskService();
  146. //获取王五任务的列表
  147. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  148. for (Task task : taskList) {
  149. //任务的id
  150. String id = task.getId();
  151. System.out.println("王五任务的id = " + id);
  152. }
  153. assignee = "赵六";
  154. taskService = processEngine.getTaskService();
  155. //获取赵六任务的列表
  156. taskList = taskService.createTaskQuery().taskAssignee(assignee).list();
  157. for (Task task : taskList) {
  158. //任务的id
  159. String id = task.getId();
  160. System.out.println("赵六任务的id = " + id);
  161. }
  162. }
  163. }

2.5.3.5 通过当前任务设置

  • 该任务必须待办任务,act_ru_task表中存在。如果该任务已经结束,就会报错。
  • 示例:
  1. package com.sunxiaping.test;
  2. import com.sunxiaping.task.Holiday;
  3. import org.activiti.engine.*;
  4. import org.activiti.engine.repository.Deployment;
  5. import org.activiti.engine.runtime.ProcessInstance;
  6. import org.activiti.engine.task.Task;
  7. import org.junit.After;
  8. import org.junit.Before;
  9. import org.junit.Test;
  10. import java.time.LocalDateTime;
  11. import java.time.ZoneId;
  12. import java.util.Date;
  13. import java.util.HashMap;
  14. import java.util.List;
  15. import java.util.Map;
  16. /**
  17. * global流程变量测试:通过当前流程实例设置
  18. *
  19. * @author <a href="mailto:1900919313@qq.com">weiwei.xu</a>
  20. * @version 1.0
  21. * 2020-08-06 14:28
  22. */
  23. public class ActivitiGlobalVariableCurrentTaskIdTest {
  24. ProcessEngine processEngine = null;
  25. @Before
  26. public void before() {
  27. ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti-cfg.xml");
  28. processEngine = configuration.buildProcessEngine();
  29. }
  30. @After
  31. public void after() {
  32. if (processEngine != null) {
  33. processEngine.close();
  34. }
  35. }
  36. /**
  37. * 流程定义部署
  38. */
  39. @Test
  40. public void testDeployment() {
  41. //获取RepositoryService对象
  42. RepositoryService repositoryService = processEngine.getRepositoryService();
  43. //获取Deployment对象
  44. Deployment deployment = repositoryService.createDeployment()
  45. .addClasspathResource("diagram/holiday.bpmn")
  46. .addClasspathResource("diagram/holiday.png")
  47. .name("请假申请流程")
  48. .deploy();
  49. String id = deployment.getId();
  50. System.out.println("流程部署的id = " + id);
  51. String name = deployment.getName();
  52. System.out.println("流程部署的名称 = " + name);
  53. String key = deployment.getKey();
  54. System.out.println("流程部署的key = " + key);
  55. }
  56. /**
  57. * 启动流程
  58. */
  59. @Test
  60. public void testStartProcessInstance() {
  61. //流程定义的key
  62. String processDefinitionKey = "holiday";
  63. //获取RuntimeService对象
  64. RuntimeService runtimeService = processEngine.getRuntimeService();
  65. //根据流程定义的key启动流程实例
  66. ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
  67. String id = processInstance.getId();
  68. System.out.println("流程实例的id = " + id);
  69. String name = processInstance.getName();
  70. System.out.println("流程实例的名称 = " + name);
  71. String processDefinitionId = processInstance.getProcessDefinitionId();
  72. System.out.println("流程定义的id = " + processDefinitionId);
  73. }
  74. /**
  75. * 测试张三完成任务
  76. */
  77. @Test
  78. public void testZhangSanTask() {
  79. String assignee = "张三";
  80. //流程定义的key
  81. String processDefinitionKey = "holiday";
  82. //获取TaskService对象
  83. TaskService taskService = processEngine.getTaskService();
  84. //获取张三任务的列表
  85. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  86. for (Task task : taskList) {
  87. //任务的id
  88. String id = task.getId();
  89. //封装global流程变量
  90. Holiday holiday = new Holiday();
  91. holiday.setNum(3f);
  92. holiday.setHolidayName("如花");
  93. holiday.setId(1);
  94. holiday.setType("年假");
  95. holiday.setReason("想男友了");
  96. holiday.setBeginDate(new Date());
  97. LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
  98. Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
  99. holiday.setEndDate(endDate);
  100. Map<String, Object> variables = new HashMap<>();
  101. variables.put("holiday", holiday);
  102. taskService.setVariables(id,variables);
  103. System.out.println("张三任务的id = " + id);
  104. taskService.complete(id);
  105. }
  106. }
  107. /**
  108. * 测试李四完成任务
  109. */
  110. @Test
  111. public void testLiSiTask() {
  112. String assignee = "李四";
  113. //流程定义的key
  114. String processDefinitionKey = "holiday";
  115. //获取TaskService对象
  116. TaskService taskService = processEngine.getTaskService();
  117. //获取李四任务的列表
  118. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  119. for (Task task : taskList) {
  120. //任务的id
  121. String id = task.getId();
  122. System.out.println("李四任务的id = " + id);
  123. taskService.complete(id);
  124. }
  125. }
  126. /**
  127. * 测试王五和赵六的任务,查看到底是王五还是赵六有任务
  128. */
  129. @Test
  130. public void testWangWuTask() {
  131. String assignee = "王五";
  132. //流程定义的key
  133. String processDefinitionKey = "holiday";
  134. //获取TaskService对象
  135. TaskService taskService = processEngine.getTaskService();
  136. //获取王五任务的列表
  137. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  138. for (Task task : taskList) {
  139. //任务的id
  140. String id = task.getId();
  141. System.out.println("王五任务的id = " + id);
  142. }
  143. assignee = "赵六";
  144. taskService = processEngine.getTaskService();
  145. //获取赵六任务的列表
  146. taskList = taskService.createTaskQuery().taskAssignee(assignee).list();
  147. for (Task task : taskList) {
  148. //任务的id
  149. String id = task.getId();
  150. System.out.println("赵六任务的id = " + id);
  151. }
  152. }
  153. }

2.5.4 注意事项

  • 如果UEL表达式中流程变量名不存在则报错。
  • 如果UEL表达式中流程变量值为null,流程不按UEL表达式去执行,而流程结束。
  • 如果UEL表达式都不符合条件,流程结束。
  • 如果连接不设置条件,会走flow序号小的那条线。

2.5.5 操作的数据库表

  • 设置流程变量会在当前执行流程变量表(act_ru_variable)插入记录,同时也会在历史流程变量表(act_hi_varinst)中也插入记录。

2.6 设置Local流程变量(实际开发中一般不用)

2.6.1 完成任务前设置

  • 在任务完成前设置Local流程变量,当前运行的Local流程变量只能在该任务结束前使用,任务结束该变量无法在当前流程实例使用,可以通过查询历史任务查询。
  • 示例:
  1. /**
  2. * 测试张三完成任务
  3. */
  4. @Test
  5. public void testZhangSanTask() {
  6. String assignee = "张三";
  7. //流程定义的key
  8. String processDefinitionKey = "holiday";
  9. //获取TaskService对象
  10. TaskService taskService = processEngine.getTaskService();
  11. //获取张三任务的列表
  12. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  13. for (Task task : taskList) {
  14. //任务的id
  15. String id = task.getId();
  16. System.out.println("张三任务的id = " + id);
  17. //封装global流程变量
  18. Holiday holiday = new Holiday();
  19. holiday.setNum(3f);
  20. holiday.setHolidayName("如花");
  21. holiday.setId(1);
  22. holiday.setType("年假");
  23. holiday.setReason("想男友了");
  24. holiday.setBeginDate(new Date());
  25. LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
  26. Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
  27. holiday.setEndDate(endDate);
  28. Map<String, Object> variables = new HashMap<>();
  29. variables.put("holiday", holiday);
  30. taskService.setVariablesLocal(id,variables);
  31. taskService.complete(id);
  32. }
  33. }

2.6.2 通过当前任务设置

  • 示例:
  1. /**
  2. * 测试张三完成任务
  3. */
  4. @Test
  5. public void testZhangSanTask() {
  6. String assignee = "张三";
  7. //流程定义的key
  8. String processDefinitionKey = "holiday";
  9. //获取TaskService对象
  10. TaskService taskService = processEngine.getTaskService();
  11. //获取张三任务的列表
  12. List<Task> taskList = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey).taskAssignee(assignee).list();
  13. for (Task task : taskList) {
  14. //任务的id
  15. String id = task.getId();
  16. //封装global流程变量
  17. Holiday holiday = new Holiday();
  18. holiday.setNum(3f);
  19. holiday.setHolidayName("如花");
  20. holiday.setId(1);
  21. holiday.setType("年假");
  22. holiday.setReason("想男友了");
  23. holiday.setBeginDate(new Date());
  24. LocalDateTime endLocalDateTime = LocalDateTime.now().plusDays(3);
  25. Date endDate = Date.from(endLocalDateTime.atZone(ZoneId.systemDefault()).toInstant());
  26. holiday.setEndDate(endDate);
  27. Map<String, Object> variables = new HashMap<>();
  28. variables.put("holiday", holiday);
  29. taskService.setVariables(id,variables);
  30. System.out.println("张三任务的id = " + id);
  31. taskService.complete(id);
  32. }
  33. }