准备工作:IDEA需要安装actibpm插件,该插件在新版本IDEA中搜不到,需要去官网自行下载,然后导入。下载地址:actibpm下载地址,下载完成后是一个actibpm.jar,在IDEA的plugins中点击install plugin from Disk导入jar包即可。
- <!--定义版本号-->
- <properties>
- <java.version>1.8</java.version>
- <slf4j.version>1.6.6</slf4j.version>
- <log4j.version>1.2.12</log4j.version>
- <activiti.version>7.0.0.Beta1</activiti.version>
- </properties>
- <dependencies>
- <!--activiti核心包-->
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-engine</artifactId>
- <version>${activiti.version}</version>
- </dependency>
- <!--activiti与spring整合的包-->
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-spring</artifactId>
- <version>${activiti.version}</version>
- </dependency>
- <!--bpmn模型处理-->
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-bpmn-model</artifactId>
- <version>${activiti.version}</version>
- </dependency>
- <!--bpmn转换-->
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-bpmn-converter</artifactId>
- <version>${activiti.version}</version>
- </dependency>
- <!--bpmn json数据转换-->
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-json-converter</artifactId>
- <version>${activiti.version}</version>
- </dependency>
- <!--bpmn布局-->
- <dependency>
- <groupId>org.activiti</groupId>
- <artifactId>activiti-bpmn-layout</artifactId>
- <version>${activiti.version}</version>
- </dependency>
- <!--bpmn云支持-->
- <dependency>
- <groupId>org.activiti.cloud</groupId>
- <artifactId>activiti-cloud-services-api</artifactId>
- <version>${activiti.version}</version>
- </dependency>
- <!--mysql驱动-->
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>8.0.11</version>
- </dependency>
- <!--mybatis-->
- <dependency>
- <groupId>org.mybatis</groupId>
- <artifactId>mybatis</artifactId>
- <version>3.4.5</version>
- </dependency>
- <!--连接池-->
- <dependency>
- <groupId>commons-dbcp</groupId>
- <artifactId>commons-dbcp</artifactId>
- <version>1.4</version>
- </dependency>
- <dependency>
- <groupId>junit</groupId>
- <artifactId>junit</artifactId>
- <version>4.12</version>
- </dependency>
- <dependency>
- <groupId>log4j</groupId>
- <artifactId>log4j</artifactId>
- <version>${log4j.version}</version>
- </dependency>
- <dependency>
- <groupId>org.slf4j</groupId>
- <artifactId>slf4j-api</artifactId>
- <version>${slf4j.version}</version>
- </dependency>
- <dependency>
- <groupId>commons-io</groupId>
- <artifactId>commons-io</artifactId>
- <version>2.4</version>
- </dependency>
- </dependencies>
- log4j.rootCategory=debug,CONSOLE,LOGFILE
-
- log4j.logger.org.apache.axis.enterprise=FATAL,CONSOLE
-
- log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
- log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
- log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
-
- log4j.appender.LOGFILE=org.apache.log4j.FileAppender
- #日志的存放路径
- log4j.appender.LOGFILE.File=d:\\SOFT\\activiti.log
- log4j.appender.LOGFILE.Append=true
- log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
- log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r[%15.15t] %-5p %30.30c %x - %m\n
- <?xml version="1.0" encoding="UTF-8"?>
- <beans xmlns="http://www.springframework.org/schema/beans"
- xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xmlns:context="http://www.springframework.org/schema/context"
- xmlns:tx="http://www.springframework.org/schema/tx"
- xsi:schemaLocation="http://www.springframework.org/schema/beans
- http://www.springframework.org/schema/beans/spring-beans.xsd
- http://www.springframework.org/schema/context
- http://www.springframework.org.schema/context/spring-context.xsd
- http://www.springframework.org/schema/tx
- http://www.springframework.org/schema/tx/spring-tx.xsd">
-
- <!--dbcp连接池-->
- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
- <!--配置数据库相关的信息-->
- <!--数据库驱动-->
- <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
- <!--数据库连接-->
- <property name="url" value="jdbc:mysql:///activitidb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8"/>
- <!--数据库用户名-->
- <property name="username" value="root"/>
- <!--数据库密码-->
- <property name="password" value="root"/>
- <property name="maxActive" value="3"/>
- <property name="maxIdle" value="1"/>
- </bean>
-
- <!--在默认方式下,这个bean的id必须是processEngineConfiguration。配置完这些内容,activiti会到指定的数据库自动生成需要的表-->
- <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
- <!--引用数据源-->
- <property name="dataSource" ref="dataSource"/>
- <!--activiti生成数据表时的策略 设置为true时:如果数据库存在相应的表,则直接使用,否则创建-->
- <property name="databaseSchemaUpdate" value="true"/>
- </bean>
- public class ActivitiUtil {
-
- /**
- *使用activiti提供的默认方式来创建mysql的表
- */
- @Test
- public void createTable(){
- //执行该方法,会在数据库自动生成activiti所需的25张表
- ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();
- System.out.println(engine);
- }
- }
| 表名 | 解释 |
|---|---|
| act_ge_bytearray | 通用的流程定义和流程资源 |
| act_ge_property | 系统相关属性 |
| act_hi_actinst | 历史的活动信息 |
| act_hi_attachment | 历史的流程附件 |
| act_hi_comment | 历史的说明性信息 |
| act_hi_detail | 历史的流程运行中的细节信息 |
| act_hi_identitylink | 历史的流程运行过程中用户关系 |
| act_hi_procinst | 历史的流程实例 |
| act_hi_taskinst | 历史的任务实例 |
| act_hi_varinst | 历史的流程运行中的变量信息 |
| act_re_deployment | 部署单元信息 |
| act_re_model | 模型信息 |
| act_re_procdef | 已部署的流程定义 |
| act_ru_event_subscr | 运行时事件 |
| act_ru_execution | 运行时流程执行实例 |
| act_ru_identitylink | 运行时用户关系信息,存储任务节点与参与者的相关信息 |
| act_ru_job | 运行时作业 |
| act_ru_task | 运行时任务 |
| act_ru_variable | 运行时变量表 |

接下来介绍如何在IDEA中创建流程定义。不过在操作之前,大家需要设置IDEA的编码格式,不然在使用bpmn时会出现中文乱码。点击菜单栏Help->Edit Custom VM options,打开文件,在文件的最后一行加入编码格式,如下所示
-Dfile.encoding=UTF-8
准备完毕后,在resources目录下创建bpmn目录,然后在bpmn目录下新建一个bpmn文件,命名随意,但最好有意义。比如我要做请假流程,此处命名为Leave.bpmn。bpmn的内容如下图所示。此处我们设置了3个节点:提交流程申请、部门经理审批和财务审批,对应的执行人分别设置为worker、manager和money。

bpmn文件的内容本质为XML文件,我们可以把新建的Leave.bpmn复制并重命名为Leave.bpmn.xml,查看相关的xml内容。其次我们还可以将绘制的流程导出图片,可供业务人员理解。具体如下:右键Leave.bpmn.xml文件,选择Diagrams–Show BPMN 2.0 Designer,弹出的文件就是图片化的流程,然后点击Export to Image File按钮,选择存储路径,就可以将图片保存下来。
- /**
- * 部署流程定义 文件上传方式
- * 就是把定义好的bpmn,保存到数据库中
- */
- @Test
- public void testDeployment() {
- //创建processEngine
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //得到RepositoryService实例
- RepositoryService repositoryService = processEngine.getRepositoryService();
- //使用repositoryService进行部署
- Deployment deployment = repositoryService.createDeployment()
- .addClasspathResource("bpmn/Leave.bpmn")//添加bpmn资源
- .addClasspathResource("bpmn/Leave.bpmn.png")//添加png资源
- .name("请假申请流程")
- .deploy();
- //输出部署信息
- System.out.println("流程部署Id:" + deployment.getId());
- System.out.println("流程部署名称:" + deployment.getName());
- }
- /*
- *启动流程实例,相当于开启一个流程
- */
- @Test
- public void testStartProcess() {
- //创建processEngine
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //获取RunTimeService
- RuntimeService runtimeService = processEngine.getRuntimeService();
- //启动流程,这个 key是当时定义Leave.bpmn时填写的id(即第一张bpmn图片,左侧蓝色框框中,id对应的值,这个是自定义的)
- ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("myLeave");
- //输出内容
- System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
- System.out.println("流程实例id:" + processInstance.getId());
- System.out.println("当前活动id:" + processInstance.getActivityId());
- }
- /**
- * 查询当前个人待执行的任务
- */
- @Test
- public void testFindPersonalTaskList() {
- //任务负责人
- String assignee = "worker";
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //创建TaskService
- TaskService taskService = processEngine.getTaskService();
- //根据流程key和任务负责人查询任务。查询流程实例,有没有需要worker执行的节点
- List<Task> list = taskService.createTaskQuery()
- //.processDefinitionKey("myLeave") //可以通过流程的key来查询
- .processInstanceId("25001") //可以通过某个流程实例的id查询
- .taskAssignee(assignee)
- .list();
- for (Task task : list) {
- System.out.println("流程实例id:" + task.getProcessInstanceId());
- System.out.println("任务id:" + task.getId());
- System.out.println("任务负责人:" + task.getAssignee());
- System.out.println("任务名称:" + task.getName());
- }
- }
- //完成任务。当worker的任务执行完毕时,该流程向前推进,到了manager需要完成的节点
- @Test
- public void completeTask() {
- //获取引擎
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //获取taskService
- TaskService taskService = processEngine.getTaskService();
- //根据流程key和任务负责人 查询任务
- //返回一个任务对象,查询实例id是25001,执行者是worker的任务
- Task task = taskService.createTaskQuery()
- // .processDefinitionKey("myLeave")
- .processInstanceId("25001")
- .taskAssignee("worker")
- .singleResult();
- //完成任务,参数:任务Id
- taskService.complete(task.getId());
- }
- //查询流程定义,一个bpmn可以定义多个流程,该方法就是查询一个bpmn下定义的所有流程
- @Test
- public void queryProcessDefinition() {
- //获取引擎
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //获取repositoryService
- RepositoryService repositoryService = processEngine.getRepositoryService();
- //得到ProcessDefinitionQuery对象
- ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
- //查询出当前所有的流程定义,查询Leave.bpmn文件定义了哪些流程(注意:Leave.bpmn在创建时,我们给他的id是myLeave)
- List<ProcessDefinition> definitionList = processDefinitionQuery.processDefinitionKey("myLeave")
- .orderByProcessDefinitionVersion()
- .desc().list();
- //输出流程定义信息
- for (ProcessDefinition processDefinition : definitionList) {
- System.out.println("流程定义id=" + processDefinition.getId());
- System.out.println("流程定义name=" + processDefinition.getName());
- System.out.println("流程定义key=" + processDefinition.getKey());
- System.out.println("流程定义version=" + processDefinition.getVersion());
- System.out.println("流程部署id=" + processDefinition.getDeploymentId());
- }
- }
- //查询某个流程下的所有进行中的流程实例
- @Test
- public void queryProcessInstance() {
- //流程定义key
- String processDefinitionKey = "myLeave";
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //获取RuntimeService
- RuntimeService runtimeService = processEngine.getRuntimeService();
- List<ProcessInstance> list = runtimeService.createProcessInstanceQuery()
- .processDefinitionKey(processDefinitionKey)
- .list();
- for (ProcessInstance processInstance : list) {
- System.out.println("------------------------");
- System.out.println("流程实例id:" + processInstance.getProcessInstanceId());
- System.out.println("所属流程定义id:" + processInstance.getProcessDefinitionId());
- System.out.println("是否执行完成:" + processInstance.isEnded());
- System.out.println("是否暂停:" + processInstance.isSuspended());
- System.out.println("当前活动标识:" + processInstance.getActivityId());
- System.out.println("业务关键字:" + processInstance.getBusinessKey());
- }
- }
- //删除流程定义
- @Test
- public void deleteDeployment() {
- //流程部署id
- String deploymentId = "2501";
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //通过流程引擎获取repositoryService
- RepositoryService repositoryService = processEngine.getRepositoryService();
- //删除流程定义,如果该流程定义已有流程实例启动,则删除时会报错
- repositoryService.deleteDeployment(deploymentId);
- //设置为true,级联删除流程定义。即使该流程有流程实例启动,也可以删除
- //repositoryService.deleteDeployment(deploymentId, true);
- }
- //下载bpmn和png文件
- @Test
- public void queryBpmnFile() throws IOException {
- //得到引擎
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //获取repositoryService
- RepositoryService repositoryService = processEngine.getRepositoryService();
- //得到查询器,设置查询条件,得到想要的流程定义
- ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
- .processDefinitionKey("myLeave")
- .singleResult();
- //通过流程定义信息,得到部署Id
- String deploymentId = processDefinition.getDeploymentId();
- //通过repositoryService的方法,实现读取图片信息和bpmn信息
- //png图片的流
- InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getDiagramResourceName());
- //bpmn文件的流
- InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, processDefinition.getResourceName());
- //构造OutputStream的流
- File file_png = new File("D:\\Leave.bpmn.png");
- File file_bpmn = new File("D:\\Leave.bpmn");
- FileOutputStream pngOut = new FileOutputStream(file_png);
- FileOutputStream bpmnOut = new FileOutputStream(file_bpmn);
- //输入流、输出流的转换
- IOUtils.copy(pngInput, pngOut);
- IOUtils.copy(bpmnInput, bpmnOut);
- //关闭流
- bpmnOut.close();
- bpmnOut.close();
- bpmnInput.close();
- pngInput.close();
- }
- //查询某个流程实例或者某个流程下的所有实例的执行情况
- @Test
- public void findHistoryInfo() {
- //得到引擎
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //获取historyService
- HistoryService historyService = processEngine.getHistoryService();
- //获取actinst表的查询对象
- HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
- //根据流程实例Id,查询单个流程实例的执行情况
- instanceQuery.processInstanceId("5001");
- //根据流程定义ID,查询该流程所有实例的执行情况
- //instanceQuery.processDefinitionId("myLeave:1:2504");
- instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
- //查询所有内容
- List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
- //输出
- for (HistoricActivityInstance hi : activityInstanceList) {
- System.out.println(hi.getActivityId());
- System.out.println(hi.getActivityName());
- System.out.println(hi.getProcessDefinitionId());
- System.out.println(hi.getProcessInstanceId());
- System.out.println("-------------------------");
- }
- }
- //启动一个流程实例时,和业务绑定起来
- @Test
- public void addBusinessKey() {
- //获取流程引擎
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //获取RuntimeService
- RuntimeService runtimeService = processEngine.getRuntimeService();
- //启动流程实例的过程中,添加businesskey
- //第一个参数:流程定义的key 第二个参数:业务关键字
- ProcessInstance instance = runtimeService.startProcessInstanceByKey("myLeave", "yeWuId");
- //输出
- System.out.println("businessKey:" + instance.getBusinessKey());
- }
- //全部流程实例的 挂起和激活
- @Test
- public void suspendAllProcessInstance() {
- //获取流程引擎
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //获取repositoryService
- RepositoryService repositoryService = processEngine.getRepositoryService();
- //查询流程定义,获取流程定义的查询对象
- ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
- .processDefinitionKey("myLeave")
- .singleResult();
- //查询当前流程定义的实例是否都是挂起状态,true表示已挂起,false表示未挂起
- boolean suspended = processDefinition.isSuspended();
- //获取流程定义的id
- String definitionId = processDefinition.getId();
- //如果是挂起状态,改为激活状态
- if (suspended) {
- //如果是挂起,可以执行激活的操作。参数1:流程定义id;参数2:是否激活;参数3:激活时间
- repositoryService.activateProcessDefinitionById(definitionId, true, null);
- System.out.println("流程定义id:" + definitionId + ",已激活");
- } else {
- //如果是激活状态,改为挂起状态。参数1:流程定义id;参数2:是否暂停;参数3:暂停时间
- repositoryService.suspendProcessDefinitionById(definitionId, true, null);
- System.out.println("流程定义id:" + definitionId + ",已挂起");
- }
- }
-
-
- //挂起和激活单个流程实例
- @Test
- public void suspendSingleProcessInstance() {
- //获取流程引擎
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //runtimeService
- RuntimeService runtimeService = processEngine.getRuntimeService();
- //查询流程实例,获取流程实例的查询对象
- ProcessInstance processInstance = runtimeService.createProcessInstanceQuery()
- .processInstanceId("5001")
- .singleResult();
- //查询当前流程定义的实例是否都是挂起状态,true表示已挂起,false表示未挂起
- boolean suspended = processInstance.isSuspended();
- //获取流程实例的id
- String instanceId = processInstance.getId();
- //如果是挂起状态,改为激活状态
- if (suspended) {
- //如果是挂起,可以执行激活的操作
- runtimeService.activateProcessInstanceById(instanceId);
- System.out.println("流程实例id:" + instanceId + ",已激活");
- } else {
- //如果是激活状态,改为挂起状态
- runtimeService.suspendProcessInstanceById(instanceId);
- System.out.println("流程实例id:" + instanceId + ",已挂起");
- }
- }


- //部署流程
- @Test
- public void testDeployment() {
- //创建processEngine
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //得到RepositoryService实例
- RepositoryService repositoryService = processEngine.getRepositoryService();
- //使用repositoryService进行部署
- Deployment deployment = repositoryService.createDeployment()
- .addClasspathResource("bpmn/evection-global.bpmn")//添加bpmn资源
- .name("出差申请流程-variables")
- .deploy();
- //输出部署信息
- System.out.println("流程部署Id:" + deployment.getId());
- System.out.println("流程部署名称:" + deployment.getName());
- }
- //启动实例
- @Test
- public void testStartProcess() {
- //创建processEngine
- ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
- //获取RunTimeService
- RuntimeService runtimeService = processEngine.getRuntimeService();
- //流程定义的key
- String key = "myEvection";
- //流程变量的map
- Map<String, Object> variables = new HashMap<String, Object>();
- //设置流程变量
- Evection evection = new Evection();
- //出差2天。这记得bpmn中定义的${evection.num}吗?用于控制流程的执行逻辑
- evection.setNum(2d);//这里的值如果大于等于3,就会走不同的分支
- //通过evection.num来判断执行流程
- variables.put("evection", evection);
- //bpmn文件中,使用uel定义的任务负责人。使用流程变量动态设置负责人
- variables.put("assignee0", "李四");
- variables.put("assignee1", "王经理");
- variables.put("assignee2", "杨总经理");
- variables.put("assignee3", "张财务");
- //启动流程
- runtimeService.startProcessInstanceByKey(key, variables);
- }
排他网关
注意: 排他网关只会选择一个为true的分支执行。如果有两个分支条件都为true,排他网关会选择id值(节点的id)较小的一条分支渠执行。如果从网关出去的线所有条件都不满足则系统抛出异常,排他网关的图片如下所示:
这个流程定义和刚才定义的出差流程是一样的,只不过引入了网关这个组件。具体的流程定义细节如下所示,先从右侧组件栏拖出组件,画出各个流程节点,并给本次流程定义id和Name赋值:
然后点击流程节点,依次给流程节点的Name和Assignee属性赋值。此处的Assignee写死了,大家也可以使用流程变量,动态地设置节点负责人:
最后我们给连线添加判断条件来控制流程走势:
进行到这里,带网关的出差流程就定义完毕了。大家可以参考之前的代码,把定义的出差流程部署到数据库中,然后启动一个流程实例(不要忘记给evection.num赋值),并推动流程节点前进就可以了,此处就不做赘述了。
并行网关
并行网关允许将流程分成多条分支,也可以把多条分支汇聚到一起,并行网关的功能是基于进入和外出顺序流的:
fork分支:并行后的所有外出顺序流,为每个顺序流都创建一个并发分支。
join汇聚:所有到达并行网关,在此等待的进入分支,直到所有进入顺序流的分支都到达以后,流程才会通过汇聚网关。
注意:如果一个并行网关有多个进入和多个外出顺序流,它就同时具有分支和汇聚功能。这时,网关会先汇聚所有进入的顺序流,然后再切分成多个并行分支。与其他网关的主要区别是,并行网关不会解析条件。即使顺序流中定义了条件,也会被忽略。
包含网关
包含网关可以看做排他网关和并行网关的结合体。和排他网关一样,可以在外出顺序流上定义条件,包含网关会解析它们。但是主要区别在于包含网关可以选择多于一条顺序流,和并行网关一样。
包含网关的功能是基于进入和外出顺序流的:
分支:所有外出顺序流的条件都会被解析,结果为true的顺序流会以并行方式继续执行,会为每个顺序流创建一个分支。
汇聚:所有并行分支到达网关,会进入等待状态,直到每个包含流程token的进入顺序流的分支都到达。这是与并行网关的最大不同,换句话说,包含网关只会等待被选中执行了的进入顺序流。在汇聚之后,流程会穿过包含网关继续执行。
结语:到这里我们就把activiti常用的功能介绍完毕了,还有一些其他的功能没有讲到,比如一个节点设置多个候选人,候选人认领、归还和交接任务等,这些功能在后期后进行完善。
24.节点设置多个候选人
act_ru_identitylink。
因为处理人除了直接设置指定人处理的方式,act_ru_identitylink表没有数据,其他的方式都是在这个表有记录的,所以还是很有必要说一下这个表结构,表结构如下图所示:
act_ru_identitylink表结构说明:
task_id 对应act_ru_task中的主键id_
type_:对应类别有starter流程实例的发起者、candidate:节点的候选人
group_id:候选组的id主键,
user_id:对应人的id_主键
rev_:版本号
其中group_id、user_id不一定是activiti工作流引擎中人员组织关系,有可能使我们自定义的人员架构关系,这一点重点说明一下,因为后面的文章,我们会讲解如何扩展工作流人员架构
第一种方式assignee
xml
- <userTask id="usertask1" name="请假审批" activiti:assignee="张三" >
- <extensionElements>
- </userTask>
我们运行的时候可以看到act_ru_task表中assignee_字段使我们设置的值
第二种方式assignee 变量方式
xml
- <userTask id="usertask1" name="请假审批" activiti:assignee="${name}" >
- <extensionElements>
- </userTask>
运行的时候把当${name}"name变量传递进去,也就是把${}里面的变量传递进去就可以,我们运行的时候可以看到act_ru_task表中assignee_字段使我们设置的值,注意这个变量传递一定要在流程还没有到达这个任务节点的时候传递,否则当流程到达这个节点的时候,在传递变量就不行了。因为当前的节点设置的是下一个节点的变量值信息。
第三种方式 候选组的方式
xml
- <userTask id="usertask1" name="请假审批" activiti:candidateUsers="a,b,c">
- </userTask>
候选组使用的时候,多个就是,分割。比如我们需要设定当前的任务处理人是a、b、c三个人处理,那我们怎么设置呢?设置的时候,我们就设置为a,b,c即可。
当流程运转到当前的节点的时候a、b、c三个人都可以查询到代办信息,然后对应的操作。
数据库的变化就是放在act_ru_identitylink中多了三条记录分别对应同一个任务id。可以参考上面说的act_ru_identitylink描述。
变量候选组
xml
- <userTask id="usertask1" name="请假审批" activiti:candidateUsers="${list}">
- </userTask>
设置的时候我们可以指定一个集合,这个集合变量,我们在程序运行的时候,也是,分割的形式,进行传递值,不过需要注意,这种方式必须是一个集合对象,而不是一个字符串类型。
看下面的两种方式赋值:
第一种方式:
String candidateUsers="a,b,c";
task.setVariable("list", candidateUsers);
这种方式是错误的,程序运行的时候会报错,报错信息就是没有分享牛原创这个集合。
正确的方式如下:
String [] candidateUsers={"a","b","c"};
task.setVariable("list", Arrays.asList(candidateUsers));
数据库的变化就是放在act_ru_identitylink中多了三条记录分别对应同一个任务id。可以参考上面说的act_ru_identitylink描述。
多角色去处理,xml配置信息对应如下所示:
xml
- <userTask id="usertask1" name="请假审批" activiti:candidateGroups="a,b,c">
- </userTask>
角色使用的时候,多个就是,分割。比如我们需要设定当前的任务处理角色是a、b、c三个角色处理,那我们怎么设置呢?设置的时候,我们就设置为a,b,c即可。
当流程运转到当前的节点的时候a、b、c三个角色都可以查询到代办信息,然后对应的操作。
数据库的变化就是放在act_ru_identitylink中多了三条记录分别对应同一个任务id。可以参考上面说的act_ru_identitylink描述。
第五种方式 角色的方式 变量方式
xml
- <userTask id="usertask1" name="请假审批" activiti:candidateGroups="${list}">
- </userTask>
设置的时候我们可以指定一个集合,这个集合变量,我们在程序运行的时候,也是,分割的形式,进行传递值,不过需要注意,这种方式必须是一个集合对象,而不是一个字符串类型。
看下面的两种方式赋值:
String candidateUsers="a,b,c";
task.setVariable("分享牛原创", candidateUsers);
这种方式是错误的,程序运行的时候会报错,报错信息就是没有分享牛原创这个集合。
正确的方式如下:
String [] candidateUsers={"a","b","c"};
task.setVariable("list", Arrays.asList(candidateUsers));
监听器方式,我们可以动态的控制,在这个监听器中,我们可以从数据库中查询出来对应的人或者角色中的人,变量的方式设置进去,达到灵活多用。
具体的监听器的配置如下:
具体的xml如下:
- <userTask id="usertask1" name="请假审批" >
- <extensionElements>
- <activiti:taskListener event="assignment" class="com.daling.bpmn.extend.MyTaskListener"></activiti:taskListener>
- </extensionElements>
- </userTask>
具体的监听实现类如下:
- public class MyTaskListener implements TaskListener {
- @Override
- public void notify(DelegateTask task) {
- String [] candidateUsers={"a","b","c"};
- task.setVariable("list", Arrays.asList(candidateUsers));
- }
-
- }
总结:
activiti 任务节点处理人的设置总结如下:
1.指定具体的处理人,可以使用变量方式设置人。也可以直接在模板中定义。
2.候选组,可以在模版中定义,不灵活。灵活的做法,可以指定一个变量赋值。
3.角色,可以在模版中定义,不灵活。灵活的做法,可以指定一个变量赋值。
4.可以使用任务监听器的方式进行赋值操作。
5.变量的方式比较灵活,模板中直接定义不灵活,因为处理节点的人或者角色可能变化