Activiti7笔记

Activiti7

什么工作流引擎

框架,将业务数据和节点的流程进行分离【特定形式进行关联】,实现节点的自动流转的工作流框架.,帮助我们实现流程自动化。

使用情景:也称为工作流

请假审批:填写申请–>主管部门–>HR审批

报销审批:填写申请–>经理批准–>总经理–>财务批准

虽然不用框架也能实现该业务需求,流程变得复杂,需要改动时,就需要耗费大量的时间成本

Activiti7框架就是这样开源出来的一套框架,可以做到流程与代码分离,帮助我们实现

一、Activiti7的内部核心机制
  1. 业务流程图需要符合规范
  2. 业务流程图的本质就是xml文件,里面的数据就是一个个的节点
  3. 解析业务流程图的过程就是解析xml文件,读取数据的过程
  4. 读取节点就是把数据存到数据库中,形成一条条的记录
  5. 后续我们只要对表进行查询就能知道流程走到哪一步 ru_task
  6. 任务完成提交就是更改数据库中表的记录,再读取下一个节点的数据
  7. 流程接受后,更改表的记录
二、BPMN

制定了一套规范,也就是业务流程图

三、使用Activiti
1. 流程:
  1. 业务流程建模,画业务流程图
  2. 部署业务流程,定义业务流程,可以理解为定义一个类,关联业务流程图 …bpmn
  3. 启动业务流程,流程实例,可以理解为创建对象
  4. 查询任务
  5. 执行任务
  6. 结束流程,如果没有下一个结点,就是任务完成
2. 环境:
  1. jdk1.8或以上
  2. mysql5或以上
  3. Tomcat8.5
  4. IDEA
  5. Activiti 7.0.0.SR1
3. 安装Activiti流程设计器(画图工具)
4.处理中文乱码
5.支持的数据库
四、集成Activiti7

SE环境,基于maven项目

1. 添加依赖
<!--添加依赖-->
    <properties>
        <slf4j.version>1.6.6</slf4j.version>
        <log4j.version>1.2.12</log4j.version>
        <activiti.version>7.0.0.SR1</activiti.version>
    </properties>
    <dependencies>
        <!-- activiti引擎 -->
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-engine</artifactId>
            <version>${activiti.version}</version>
        </dependency>
        <!-- 整合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>
        <!-- mysql驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</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>
        <!-- log start -->
        <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>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <!-- log end -->
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.6</version>
        </dependency>
        <!--数据库连接池-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.4</version>
        </dependency>
    </dependencies>
2. 添加日志文件

在resource文件夹中创建log4j.properties文件

# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
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
# LOGFILE is set to be a File appender using a PatternLayout.
log4j.appender.LOGFILE=org.apache.log4j.FileAppender
log4j.appender.LOGFILE.File=./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
3.添加核心配置文件

在resource文件夹中创建名为 activiti.cfg.xml 的文件,文件名是固定的,不按规则命名会报错

<?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/contex
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
	<!--添加数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver" />
        <property name="url" value="jdbc:mysql:///activiti"/>
        <property name="username" value="root"/>
        <property name="password" value="admin"/>
    </bean>


    <!-- 默认id对应的值 为processEngineConfiguration -->
    <bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
        <property name="dataSource" ref="dataSource"/>
        <!--
            activiti数据库表处理策略
                false(默认值):检查数据库的版本和依赖库的版本,如果不匹配就抛出异常
                true:构建流程引擎时,执行检查,如果需要就执行更新。如果表不存在,就创建。
                create-drop:构建流程引擎时创建数据库报表,关闭流程引擎时就删除这些表。
                drop-create:先删除表再创建表。
                create:构建流程引擎时创建数据库表,关闭流程引擎时不删除这些表
        -->
        <property name="databaseSchemaUpdate" value="true"/>
    </bean>
</beans>
五、数据库表的说明
1. 介绍

Activiti是通过操作数据库中的表单来实现工作流的。不同的环境中,表的数量也是不一样的。

此环境中有25张表。

  1. 每一种表都对应着一个Service
  2. 命名规则
    1. "act_re"开头的表,re表示 Repository,与流程定义有关
    2. "act_ru"开头的表,,ru表示RunTime,与流程实例,任务处理有关,只保存正在执行中的任务的数据
    3. "act_hi"开头的表,,hi表示History,记录流程,变量,任务等的历史信息
    4. "act_ge"开头的表,ge表示General,记录通用数据
2. 常用表
  1. 流程定义—>RepositoryService

    1. act_ge_bytearray:用于存储bpmn的数据

    2. act_ge_property:用于生产主键等,是内部表,我们一般不需要关注

    3. act_re_deployment:部署信息表

    4. act_re_procdef:流程定义表

  2. 流程实例—>RunTimeService

    1. act_ge_property:主键更新
    2. act_hi_actinst:历史节点表,记录所有开始,任务,结束节点的信息
    3. act_hi_identitylink:历史身份表,记录所有用户的信息
    4. act_hi_procinst:历史流程表:记录所有流程实例的信息
    5. act_hi_taskinst:历史任务表:记录所有任务对象的信息
    6. act_ru_execution:运行时流程执行实例表
    7. act_ru_identitylink:运行时用户信息表,
    8. act_ru_task:运行时任务信息表
  3. 执行任务—>taskService

    1. act_hi_actinst:历史节点表,记录所有开始,任务,结束节点的信息
    2. act_hi_identitylink:历史身份表,记录所有用户的信息
    3. act_hi_taskinst:历史任务表:记录所有任务对象的信息
    4. act_ru_execution:运行时流程执行实例表
    5. act_ru_identitylink:运行时用户信息表,
    6. act_ru_task:运行时任务信息表
六、流程引擎的API
接口作用
RepositoryService进行资源管理,流程定义
RunTImeService进行流程实例
TaskService进行任务管理
HistoryService进行历史管理
ManagementService进行引擎管理
七、Activiti7的入门
1. bpmn的制作
image-20220529144831975 image-20220529144851096

bpmn的id和Name是自定义的

image-20220529145102000

给任务节点设置名字,给上执行人,后续执行人可以使用UEL表达式,监听器来设置,也可以通过候选人方式设置。

2. 流程定义
@Test
public void test1() {
    //1 获取流程引擎对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    //2 获取仓库Service, RespositoryService
    processEngine.getRepositoryService()
            .createDeployment()
            .addClasspathResource("bpmn/act3.bpmn")
            .deploy();
	//一个deploye对应一个流程定义
}
3.流程实例
@Test
public void test2() {
    processEngine.getRuntimeService()
            .startProcessInstanceByKey("bpmn图中id");//自定义的流程名称
}
4.执行任务
@Test
public void test3(){
    /*
    	参数为该任务的id,可以用TaskService提供query方法进行任务的查询
   		添加评论要在任务提交前执行
    	添加评论 taskService.addComent(taskId,processInstanceId,messag);
    	多个对象用list(),唯一用singleResult()
    */
   ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        TaskService taskService = processEngine.getTaskService();
        taskService
                .createTaskQuery()
                .processDefinitionKey("leaveProcess")//查询条件
                .taskAssignee("张三")//查询条件
                .list().forEach(task -> {
            taskService.addComment(task.getId(), task.getProcessInstanceId(), "不干了");
            taskService.complete(task.getId());
        });
}
5.查看历史情况
@Test
    public void test10() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        HistoryService historyService = processEngine.getHistoryService();
        historyService.createHistoricProcessInstanceQuery()
                .processDefinitionKey("leaveProcess")
                .list()
                .forEach(historicProcessInstance -> {
                    System.out.println(historicProcessInstance.getId());
                });
    }
八、Activiti7的进阶
一、流程定义相关
  1. 查询流程相关信息,包含流程定义,流程部署,流程定义版本
@Test
public void testDefinitionQuery(){
    //创建ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    //获取仓库服务
    RepositoryService repositoryService = processEngine.getRepositoryService();
    //获取流程定义集合
    List<ProcessDefinition> processDefinitionList = repositoryService
            .createProcessDefinitionQuery()
            .processDefinitionKey("leaveProcess")
            .list();
    //遍历集合
    for (ProcessDefinition definition:processDefinitionList){
        System.out.println("流程定义ID:"+definition.getId());
        System.out.println("流程定义名称:"+definition.getName());
        System.out.println("流程定义key:"+definition.getKey());
        System.out.println("流程定义版本:"+definition.getVersion());
        System.out.println("流程部署ID:"+definition.getDeploymentId());
        System.out.println("====================");
    }
}

2.现在我们的流程资源文件已经上传到数据库了,如果其他用户想要查看这些资源文件,可以从数据库中把资源文件下载到本地。

@Test
public void testDownloadResource() throws Exception {
    //创建ProcessEngine对象
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    //获取仓库服务
    RepositoryService repositoryService = processEngine.getRepositoryService();
    //获取流程定义集合
    List<ProcessDefinition> list = repositoryService
            .createProcessDefinitionQuery()
            .processDefinitionKey("leaveProcess")
            .orderByProcessDefinitionVersion()//按照版本排序
            .desc()//降序
            .list();
    //获取最新那个
    ProcessDefinition definition =list.get(0);
    //获取部署ID
    String deploymentId = definition.getDeploymentId();
    //获取bpmn的输入流
    InputStream bpmnInput = repositoryService.getResourceAsStream(
                                        deploymentId,
                                        definition.getResourceName());
    //获取png的输入流
    InputStream pngInput = repositoryService.getResourceAsStream(
                                        deploymentId,
                                        definition.getDiagramResourceName());
    //设置bpmn输入
    FileOutputStream bpmnOutPut = new FileOutputStream("D:/leave.bpmn");
    //设置png输入
    FileOutputStream pngOutPut = new FileOutputStream("D:/leave.png");
    IOUtils.copy(bpmnInput,bpmnOutPut);
    IOUtils.copy(pngInput,pngOutPut);
}

3.根据部署Id删除对应的流程定义

如果流程定义 没有流程实例可以直接删除

如果流程定义 已近有流程实例,可以通过一个参数 true 进行级联删除

@Test
public void test3(){
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    processEngine.getRepositoryService().deleteDeployment("5001",true);
}
二、流程实例相关

框架,将业务数据和节点的流程进行分离【特定形式进行关联】,特定形式指的就是businessKey

businessKey
搞清楚businessKey 作用?
把我们的业务数据和流程绑定起来 , 因为在审核的时候 , 审核人妖看到用户申请信息.
步骤
1 用户在申请的时候填写信息 ,最终把信息保存到业务表中
2 先画出bpmn流程 ,把流程图 部署到activiti当中
3 小陈发起申请, 在activiti 开启流程实例 , 在启动流程时候就会把businessKey 和流程实例绑定起来
4 任务走了部门经理节点 , 这里是一个任务, 我们是可以通过任务拿到流程实例id
5 通过流程实例id拿到流程实例 , 就可以通过流程实例那businessKey
6 根据businessKey 上业务表中取查询数据 , 审核人在根据查询的数据看是否通过

public class Demo {

    /**
     * 获取businessKey
     */
    //流程定义
    @Test
    public void test1() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRepositoryService()
                .createDeployment()
                .addClasspathResource("bpmn/act3.bpmn")
                .deploy();

    }

    //流程实例+添加businessKey
    @Test
    public void test2() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRuntimeService()
                .startProcessInstanceByKey("act3", "2887");
    }

    //在任务中获取实例id,通过实例id获取实例对象,通过实例对象获取businessKey
    @Test
    public void test3() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        String processInstanceId = processEngine.getTaskService()
                .createTaskQuery()
                .singleResult()
                .getProcessInstanceId();

        String businessKey = processEngine
                .getRuntimeService()
                .createProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult()
                .getBusinessKey();

        System.out.println("businessKey = " + businessKey);
    }
}

三、流程定义/实例挂起/激活

例如公司制度改变过程中的流程, 总经理更换过程中的流程,有100个人的流程, 70个人已经完成,30个人流程正好在总经理更换中,就需要挂起.

  1. 比如我们的业务流程为:

【开始节点】–>【A节点】–>【B节点】–>【C节点】–>【结束节点】

【C节点】的业务逻辑需要和外部接口交互,刚好外部接口出问题了,如果剩下的流程都走到【C节点】,执行【C节点】的业务逻辑,那都会报错,我们就可以把流程挂起,等待外部接口可用之后再重新激活流程.

  1. 业务流程发生改变,已经发起的流程实例继续按照旧的流程走,如果新发起的流程就按照新的业务流程走.这时候我们就需要挂起流程定义,但是不挂起流程实例.
  • 操作流程定义为挂起状态,该操作定义下面的所有的流程实例将全部暂停。
  • 流程定义为挂起状态,该流程定义下将不允许启动新的流程实例,同时该流程定义下的所有流程实例将全部挂起暂停执行
public class Demo {

    /**
     * 流程定义的挂起与激活
     */

    //定义流程
    @Test
    public void test1() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRepositoryService()
                .createDeployment()
                .addClasspathResource("bpmn/act4.bpmn")
                .deploy();
    }

    //流程实例
    @Test
    public void test2() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRuntimeService()
                .startProcessInstanceByKey("act4");
    }

    //进行流程挂起
    @Test
    public void test3() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        ProcessDefinition processDefinition = processEngine.getRepositoryService().
                createProcessDefinitionQuery()
                .singleResult();
        processEngine.getRepositoryService().suspendProcessDefinitionById(processDefinition.getId());
    }

    //查询流程挂起状态
    @Test
    public void test4() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        System.out.println(processEngine.getRepositoryService()
                .createProcessDefinitionQuery()
                .singleResult().isSuspended());//true
    }

    //可以完成未完成的任务
    @Test
    public void test5() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        Task task = processEngine.getTaskService()
                .createTaskQuery()
                .singleResult();
        processEngine.getTaskService().complete(task.getId());
    }

    //但不能再流程实例
    @Test
    public void test6() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRuntimeService()
                .startProcessInstanceByKey("act4");
    }

    //重新激活流程定义+测试+执行新实例任务
    @Test
    public void test7() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService
                .createProcessDefinitionQuery()
                .singleResult();
        if (processDefinition.isSuspended()) {
            System.out.println("to true");
            repositoryService.activateProcessDefinitionById(processDefinition.getId());

            System.out.println("流程实例");
            processEngine.getRuntimeService()
                    .startProcessInstanceByKey("act4");

            System.out.println("执行任务");
            TaskService taskService = processEngine.getTaskService();
            Task task = taskService.createTaskQuery().taskAssignee("张三").singleResult();
            taskService.complete(task.getId());
        }
    }

    //挂起后不能执行任务和进行流程定义
    @Test
    public void test8() {
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService
                .createProcessDefinitionQuery()
                .singleResult();
        repositoryService
                .suspendProcessDefinitionById(processDefinition.getId(), true, null);
    }

    //不能进行流程定义
    @Test
    public void test9(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getRuntimeService()
                .startProcessInstanceByKey("act4");
    }
    //不能执行任务
    @Test
    public void test10(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        processEngine.getTaskService().complete("10005");
    }

    //挂起实例
    @Test
    public void test11(){
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        //把原来的挂起的流程定义激活
        RepositoryService repositoryService = processEngine.getRepositoryService();
        ProcessDefinition processDefinition = repositoryService
                .createProcessDefinitionQuery()
                .singleResult();
    
        //挂起实例
        RuntimeService runtimeService = processEngine.getRuntimeService();
        runtimeService.suspendProcessInstanceById("10001");
        //检测是否挂起,若已近挂起,就重新激活,并执行任务
        TaskService taskService = processEngine.getTaskService();
        Task task = taskService.createTaskQuery()
                .taskAssignee("张三")
                .singleResult();
        //获取实例id
        String processInstanceId = task.getProcessInstanceId();
        //判断是否已近挂起
        boolean suspended = runtimeService.createProcessInstanceQuery()
                .processInstanceId(processInstanceId)
                .singleResult()
                .isSuspended();
        if (suspended) {
            System.out.println("======================");
            System.out.println("激活");
            runtimeService.activateProcessInstanceById(processInstanceId);
            taskService.complete(task.getId());
        }
    }
}
三、任务分配

指的就是指定处理任务的人,分配方法有三种

1.固定分配 直接把名字写死,在实际开发过程中,此方法不适应。但在测试时使用比其他的方法都方便。

​ 只要在任务结点中的 Assignee属性中设置值

  1. 使用EUL表达式,是一种占位符,在任务结点中的 Assignee属性中设置${value}。需要把处理人添加到流程实例,就要在流程实例时,添加参数 ,以map的方式添加。

    public class UEL {
    
        /**
         * 分配负责人
         */
    
        //流程定义
        @Test
        public void test1() {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            processEngine.getRepositoryService()
                    .createDeployment()
                    .addClasspathResource("bpmn/act5.bpmn")
                    .deploy();
        }
    
        //实例部署
        @Test
        public void test2() {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            Map<String, Object> map = new HashMap<>();
            map.put("s1", "张三");
            map.put("s2", "lisi");
            processEngine.getRuntimeService()
                    .startProcessInstanceByKey("act5", map);
        }
    
        //查询候选人
        @Test
        public void test3() {
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            Task lisi = processEngine.getTaskService()
                    .createTaskQuery()
                    .taskCandidateOrAssigned("lisi").singleResult();
        }
        //领任务
        @Test
        public void test4(){
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
    
            processEngine.getTaskService().claim("17507","lisi");
        }
    
        //执行任务
        @Test
        public void test5(){
            ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
            processEngine.getTaskService().complete("17507");
        }
    }
    
    1. 监听器

      任务监听器是发生对应的任务相关事件时执行自定义的Java逻辑或表达式。

      任务相关事件包括:

      • Event:触发事件
        • Create:任务创建后触发。
        • Assignment:任务分配后触发。
        • Delete:任务完成后触发。
        • All:所有事件发生都触发。
    2. 自定义一个任务监听器类,然后此类必须实现org.activiti.engine.delegate.TaskListener接口

      package cn.wolfcode;
      
      import org.activiti.engine.delegate.DelegateTask;
      import org.activiti.engine.delegate.TaskListener;
      
      /**
       * Created by wolfcode
       */
      public class AssigneeTaskListener implements TaskListener {
          public void notify(DelegateTask delegateTask) {
              if(delegateTask.getName().equals("部门经理审批")){
                  delegateTask.setAssignee("赵六");
              }else if(delegateTask.getName().equals("部门经理审批")){
                  delegateTask.setAssignee("孙七");
              }
          }
      }
      
    3. 在bpmn文件中配置监听器

      [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uzt3J72y-1653831176864)(E:/CodeWolf/20220215/阶段四/07 Activit/讲义/图片/image-20210603114503828.png)]

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

四、流程变量

​ 在流程中,可以通过变量来控制流程的走向,从而增强业务能力。

  1. 局部变量(少用)
  2. 全局变量(多用)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GXacHjjK-1653831176865)(C:\Users\SKY\AppData\Roaming\Typora\typora-user-images\image-20220529172114148.png)]

3. 使用方法
  	1. 在流程实例时,添加一个map为参数,Map<String,Object> ,String为变量名,Object为值
4. 特殊情况
  	1. 当两个情况都满足,在不添加其他操作时,两个任务都会被触发
  	2. 当两个情况都不满足时,会抛出异常,说找不到出口
五、任务候选人
1. 在实际运用的过程中,任务的执行人不是固定的,而是从几个人中,拿一个人出来执行便可
2. 在Condidata中,通过添加候选人,可以添加多个,中间使用逗号隔开
3. 在流程实例后,候选人领取任务前,该任务是没有执行人的
4. 候选人执行任务
  	1. 要使用TaskServicet提供的 claim(String taskId,String userId),进行领取任务
  	2. 使用 taskSerice.commit(Strinig taskId)执行任务
六、网关
  1. 排他网关

    1. 当流程走到这个网关是,所有的分支都会进行判断,表达式为true的分支就是流程走向
    2. 如果分支都为true,就会选择id小的分支
    3. 当分支都为false时,会报错,说流程找不到出口
  2. 并行网关

    1. 需要两个网关,把所有分支都夹起来
    2. 只有里面的分支全都走完,流程才能到下一个结点
  3. 包含网关

    1. 可以看成是排他网关与并行网关的集合体

    2. 需要两个网关,把所有分支都夹起来

    3. 使用场景:请假规则

      1. 请假<3天的副经理批准
      2. 请假>3天的总经理批准
      3. 请假无论多少天都需要人事部门批准

候选人,需要先使用claim进行领取任务,在执行任务

g为变量名,Object为值
4. 特殊情况
1. 当两个情况都满足,在不添加其他操作时,两个任务都会被触发
2. 当两个情况都不满足时,会抛出异常,说找不到出口

五、任务候选人
1. 在实际运用的过程中,任务的执行人不是固定的,而是从几个人中,拿一个人出来执行便可
2. 在Condidata中,通过添加候选人,可以添加多个,中间使用逗号隔开
3. 在流程实例后,候选人领取任务前,该任务是没有执行人的
4. 候选人执行任务
  	1. 要使用TaskServicet提供的 claim(String taskId,String userId),进行领取任务
  	2. 使用 taskSerice.commit(Strinig taskId)执行任务
六、网关
  1. 排他网关

    1. 当流程走到这个网关是,所有的分支都会进行判断,表达式为true的分支就是流程走向
    2. 如果分支都为true,就会选择id小的分支
    3. 当分支都为false时,会报错,说流程找不到出口
  2. 并行网关

    1. 需要两个网关,把所有分支都夹起来
    2. 只有里面的分支全都走完,流程才能到下一个结点
  3. 包含网关

    1. 可以看成是排他网关与并行网关的集合体

    2. 需要两个网关,把所有分支都夹起来

    3. 使用场景:请假规则

      1. 请假<3天的副经理批准
      2. 请假>3天的总经理批准
      3. 请假无论多少天都需要人事部门批准
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值