SpringBoot多数据源环境集成工作流引擎Activiti(巨详细)

0.工作流引擎Activiti介绍

Alfresco软件在2010年5月17日宣布Activiti业务流程管理(BPM)开源项目的正式启动,其首席架构师由业务流程管理BPM的专家 Tom Baeyens担任,Tom Baeyens就是原来jbpm的架构师,而jbpm是一个非常有名的工作流引擎,当然activiti也是一个工作流引擎。

Activiti是一个工作流引擎, activiti可以将业务系统中复杂的业务流程抽取出来,使用专门的建模语言BPMN2.0进行定义,业务流程按照预先定义的流程进行执行,实现了系统的流程由activiti进行管理,减少业务系统由于流程变更进行系统升级改造的工作量,从而提高系统的健壮性,同时也减少了系统开发维护成本。

官方网站:https://www.activiti.org/

1.maven依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>com.disw</groupId>
  <artifactId>activiti_test</artifactId>
  <version>1.0-SNAPSHOT</version>

  <!-- 集成SpringBoot父项目:SpringBoot项目的标志 -->
  <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.5.6</version>
  </parent>
  <properties>
    <slf4j.version>1.6.6</slf4j.version>
    <log4j.version>1.2.12</log4j.version>
    <activiti.version>5.22.0</activiti.version>
  </properties>

  <dependencies>
    <!-- 支持web环境,不用写版本号 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!-- 处理JSON的依赖 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.47</version>
    </dependency>
    <!-- 数据库的jar包 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <!-- SpringBoot2.2.5的版本中Mysql是mysql8.0的,需要手动导入8以下的版本。我们电脑中安装的数据库是mysql5.x的,mysql8.0启动包都不一样,所以需要手动导入5.x的版本。避免链接数据库出现问题 -->
      <version>5.1.38</version>
    </dependency>
    <!--mysql数据库驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <!--mybatis-plus-boot-starter-->
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus-boot-starter</artifactId>
      <version>3.4.1</version>
    </dependency>
    <!-- Lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
    </dependency>
    <!-- form数据验证依赖 -->
    <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>
    <!--    lang3工具包    -->
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-lang3</artifactId>
      <version>3.1</version>
    </dependency>
    <dependency>
      <groupId>cn.hutool</groupId>
      <artifactId>hutool-all</artifactId>
      <version>5.8.16</version>
    </dependency>
    <!--knife4j-->
    <dependency>
      <groupId>com.github.xiaoymin</groupId>
      <artifactId>knife4j-spring-boot-starter</artifactId>
      <version>2.0.7</version>
    </dependency>
    <dependency>
      <groupId>io.springfox</groupId>
      <artifactId>springfox-boot-starter</artifactId>
            <version>3.0.0</version>
            <exclusions>
                <exclusion>
                    <groupId>io.swagger</groupId>
                    <artifactId>swagger-models</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 防止进入swagger页面报类型转换错误,排除3.0.0中的引用,手动增加1.6.2版本 -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-models</artifactId>
            <version>1.6.2</version>
        </dependency>
        <!--整合Redis , 底层可以用jedis-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>
        <dependency>
            <groupId>com.google.guava</groupId>
            <artifactId>guava</artifactId>
            <version>29.0-jre</version>
        </dependency>

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.2.1</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>${commons-lang3.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>${logback.version}</version>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.11</version>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter-basic</artifactId>
            <version>5.22.0</version>
            <exclusions>
                <exclusion>
                    <artifactId>commons-io</artifactId>
                    <groupId>commons-io</groupId>
                </exclusion>
                <exclusion>
                    <artifactId>mybatis</artifactId>
                    <groupId>org.mybatis</groupId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>
</project>

2.yaml文件配置

spring:
  profiles:
    active: test
---
server:
  port: 9987
spring:
  profiles: test
  activiti:
    #false关闭spring自动部署   true则是每次启动spring容器都会进行部署
    check-process-definitions: false
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    dynamic:
      primary: master
      strict: true
      datasource:
        master:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf-8&useTimezone=true&serverTimezone=Asia/Shanghai&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&failOverReadOnly=false&nullCatalogMeansCurrent=true&useLegacyDatetimeCode=false
          username: root
          password: root
        salve:
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://localhost:3306/activiti-test?useUnicode=true&characterEncoding=utf-8&useTimezone=true&serverTimezone=Asia/Shanghai&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&failOverReadOnly=false&nullCatalogMeansCurrent=true&useLegacyDatetimeCode=false
          username: root
          password: root
    hikari:
      # 是否自动提交
      auto-commit: true
      # 如果在没有连接可用的情况下超过此时间,则将抛出SQLException
      # 数据库连接超时时间,默认30秒,即30000
      connection-timeout: 30000
      # 控制允许连接在池中空闲的最长时间
      idle-timeout: 180000
      # 控制池中连接的最长生命周期。使用中的连接永远不会退役,只有当它关闭时才会被删除
      max-lifetime: 1800000
      # 如果您的驱动程序支持JDBC4,强烈建议不要设置此属性
      # connection-test-query: select 1
      # 控制HikariCP尝试在池中维护的最小空闲连接数。建议不要设置此值,而是允许HikariCP充当固定大小的连接池。 默认值:与maximumPoolSize相同
      # minimum-idle:
      # 连接池中允许的最大连接数。缺省值:10;推荐的公式:((core_count * 2) + effective_spindle_count)
      maximum-pool-size: 34
      #登录超时设置
      login-timeout: 500
      #检验连接超时
      validation-timeout: 3000

#mybatis plus 设置
mybatis-plus:
  type-aliases-package: com.disw.*.*.entity #扫描实体类所在的包
  mapper-locations: classpath*:com/disw/*/*Mapper.xml
  global-config:
    # 关闭MP3.0自带的banner
    banner: false
    db-config:
      #主键类型  0:"数据库ID自增",1:"该类型为未设置主键类型", 2:"用户输入ID",3:"全局唯一ID (数字类型唯一ID)", 4:"全局唯一ID UUID",5:"字符串全局唯一ID (idWorker 的字符串表示)";
      id-type: auto
      # 默认数据库表下划线命名
      table-underline: true
# Swagger配置
swagger:
  # 是否开启swagger
  enabled: true
  # 请求前缀
  pathMapping: /



3.basic基础配置

package com.disw.basic.config;


import com.disw.basic.constant.PlatformConstants;
import com.github.xiaoymin.knife4j.spring.annotations.EnableKnife4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import springfox.bean.validators.configuration.BeanValidatorPluginsConfiguration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

/**
 * @author sunxl
 * @date 2023/6/15 15:34
 */
@Configuration
@EnableSwagger2
@EnableKnife4j
@Import(BeanValidatorPluginsConfiguration.class)
@ConditionalOnExpression("${swagger.enable:true}")
public class SwaggerConfig {


    @Bean
    public Docket createOpenRestApi() {
        ParameterBuilder tokenPar = new ParameterBuilder();
        List<Parameter> pars = new ArrayList<>();
        //header中的token参数非必填,传空也可以
        tokenPar.name(PlatformConstants.AUTHORIZATION).description("token")
        .modelRef(new ModelRef("string")).parameterType("header")
        .required(false).build();
        pars.add(tokenPar.build());

        return new Docket(DocumentationType.SWAGGER_2)
        .groupName("1、Activiti接口")
        .apiInfo(new ApiInfoBuilder().title("Activiti接口文档").description("Activiti接口").version("1.0-SNAPSHOT").build())
        .select()
        为当前包路径
        .apis(RequestHandlerSelectors.basePackage("com.disw.activiti"))
        .paths(PathSelectors.any())
        .build()
        .globalOperationParameters(pars);
    }

    private ApiInfo apiCoreInfo() {
        return new ApiInfoBuilder()
        .title("activiti测试接口文档")
        .description("activiti测试接口文档")
        .version("1.0")
        .build();
    }
}

4.启动类

package com.disw;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//一定要排除该类,否则会报错
@SpringBootApplication(exclude = {org.activiti.spring.boot.SecurityAutoConfiguration.class})
@MapperScan("com.disw.*.*.mapper")
public class ActivitiApp {
    public static void main(String[] args) {
        SpringApplication.run(ActivitiApp.class,args);
    }
}

5.结构演示

6.测试用的bomn

6.1idea的bpmn的插件

6.2测试流程的.bpmn的xml以及流程图的png图片

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="ask_leave" name="请假流程" isExecutable="true">
    <startEvent id="sid-1a506f9f-e07e-4958-9dd8-3efdfaa35ce0" name="开始"/>
    <userTask id="sid-7a9717f0-76b0-42d2-9796-4cbbe796b297" activiti:assignee="李四" name="请假提交"/>
    <userTask id="sid-9f06fc5a-2c35-4ebf-b033-1ce0d48d757c" name="小领导审核" activiti:assignee="王五"/>
    <userTask id="sid-5bf93ee5-5e60-4af9-9179-74f657bc17e9" name="大领导审核"/>
    <sequenceFlow id="sid-99e9d9d3-8c63-462f-904e-dae887fffc63" sourceRef="sid-1a506f9f-e07e-4958-9dd8-3efdfaa35ce0" targetRef="sid-7a9717f0-76b0-42d2-9796-4cbbe796b297"/>
    <sequenceFlow id="sid-59057c5f-be9b-402f-bebd-cc5dc209c9b8" sourceRef="sid-7a9717f0-76b0-42d2-9796-4cbbe796b297" targetRef="sid-9f06fc5a-2c35-4ebf-b033-1ce0d48d757c"/>
    <sequenceFlow id="sid-0cd4db92-4214-40cd-bd2e-1bda570b0886" sourceRef="sid-9f06fc5a-2c35-4ebf-b033-1ce0d48d757c" targetRef="sid-5bf93ee5-5e60-4af9-9179-74f657bc17e9"/>
    <endEvent id="sid-5d70f827-e86e-442b-bac6-1bf4a4b8e8e5" name="结束"/>
    <sequenceFlow id="sid-cf92a941-4991-40ec-8caa-749e93130b64" sourceRef="sid-5bf93ee5-5e60-4af9-9179-74f657bc17e9" targetRef="sid-5d70f827-e86e-442b-bac6-1bf4a4b8e8e5"/>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_请假">
    <bpmndi:BPMNPlane bpmnElement="ask_leave" id="BPMNPlane_请假">
      <bpmndi:BPMNShape id="shape-37be0224-dbc8-40b4-972a-94e855d5e76c" bpmnElement="sid-1a506f9f-e07e-4958-9dd8-3efdfaa35ce0">
        <omgdc:Bounds x="-185.0" y="-100.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-589d98e5-f019-4859-98ca-3bff2b63fd66" bpmnElement="sid-7a9717f0-76b0-42d2-9796-4cbbe796b297">
        <omgdc:Bounds x="-80.0" y="-125.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="sid-6e512bff-a052-4430-8abb-37ac081d0473" bpmnElement="sid-9f06fc5a-2c35-4ebf-b033-1ce0d48d757c">
        <omgdc:Bounds x="-80.0" y="15.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-e3c3efdb-6e80-4203-8f45-43372cf003be" bpmnElement="sid-5bf93ee5-5e60-4af9-9179-74f657bc17e9">
        <omgdc:Bounds x="130.0" y="15.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-d22fa1cc-b4df-4540-a3df-327647d18dd7" bpmnElement="sid-99e9d9d3-8c63-462f-904e-dae887fffc63">
        <omgdi:waypoint x="-155.0" y="-85.0"/>
        <omgdi:waypoint x="-80.0" y="-85.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-532f1a36-3270-448c-9b40-5d65b9356277" bpmnElement="sid-59057c5f-be9b-402f-bebd-cc5dc209c9b8">
        <omgdi:waypoint x="-30.0" y="-45.0"/>
        <omgdi:waypoint x="-30.0" y="15.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-a67370a2-91a6-479d-87e9-ed9694ec26fc" bpmnElement="sid-0cd4db92-4214-40cd-bd2e-1bda570b0886">
        <omgdi:waypoint x="20.0" y="55.0"/>
        <omgdi:waypoint x="130.0" y="55.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="shape-51c985c6-393f-4a9b-8b55-69bf6fbe03f3" bpmnElement="sid-5d70f827-e86e-442b-bac6-1bf4a4b8e8e5">
        <omgdc:Bounds x="350.0" y="40.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-cef1f656-0776-40ca-afbd-e14f3525502c" bpmnElement="sid-cf92a941-4991-40ec-8caa-749e93130b64">
        <omgdi:waypoint x="230.0" y="55.0"/>
        <omgdi:waypoint x="350.0" y="55.0"/>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

7.项目启动

7.1数据库生成activiti相关表

可以看见,只有activiti生成了数据表,而activiti没有生成数据表,因为多数据源没有指定的时候会默认使用master的数据源

7.2项目的接口文档

浏览器地址栏输入:http://localhost:9987/doc.html进入接口文档

8.部署流程演示

8.1spring自动部署

项目启动的时候spring框架会自动部署一次,并且会将你在bpmn中定义的id、名称以及bpmn的资源路径部署进activiti

8.2通过spring手动部署流程

8.3非spring部署流程

9.Activiti所有的servicei

Activiti引擎提供了7大Service接口,均通过processEngine获取,支持链式API风格。

RepositoryService流程仓库服务,管理流程仓库,比如部署、删除、读取流程资源IdentityService身份服务,管理用户、组及其关系

RuntimeService运行服务,处理所有正在运行态的流程实例、任务等。

TaskService任务服务,管理(签收、办理、指派等)、查询任务。

FormService表单服务,读取和流程、任务相关的表单数据

HistoryService历史服务,管理所有历史数据

ManagementService引擎管理服务,和具体业务无关,管理引擎。

10.流程部署信息和定义信息的查询

10.1可以获得的数据

RepositoryService repositoryService = processEngine.getRepositoryService();

List<Deployment> list = repositoryService.createDeploymentQuery().list();

List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().list();

System.out.println("流程部署对象的查询:");
list.forEach(e->{
    System.out.println(e.getId());
    System.out.println(e.getName());
    System.out.println(e.getCategory());
    System.out.println(e.getTenantId());
    System.out.println(e.getDeploymentTime());
});
System.out.println("流程部署定义对象的查询:");
processDefinitions.forEach(e->{
    System.out.println(e.getId());
    System.out.println(e.getVersion());
    System.out.println(e.getKey());
    System.out.println(e.getCategory());
    System.out.println(e.getDescription());
    System.out.println(e.getDeploymentId());
    System.out.println(e.getDiagramResourceName());
    System.out.println(e.getResourceName());
    System.out.println(e.getTenantId());
    System.out.println(e.getName());
});

10.2效果

10.3查询条件的使用

11.流程

11.1发起流程

@Override
public void insertProcessInstance() {
    RuntimeService runtimeService = processEngine.getRuntimeService();
    RepositoryService repositoryService = processEngine.getRepositoryService();
    //根据流程定义的id来创建流程
    //创建请假流程
    ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().processDefinitionName("请假流程").singleResult();
    //普通的发起流程
    ProcessInstance processInstance = runtimeService.startProcessInstanceById(processDefinition.getId());
    //带业务键的发起流程
    ProcessInstance processInstance1 = runtimeService.startProcessInstanceById(processDefinition.getId(),"业务键");
    //返回的ProcessInstance对象里包含创建任务的值
    System.out.println(processInstance.getName());
    System.out.println(processInstance.getBusinessKey());
    System.out.println(processInstance.getDeploymentId());
    System.out.println(processInstance.getProcessDefinitionName());
    System.out.println(processInstance.getProcessDefinitionId());
    System.out.println(processInstance.getProcessDefinitionVersion());
}

11.2待办任务查询以及审批

    @Override
    public void completeProcessInstance(String assignee) {
        //创建service
        TaskService taskService = processEngine.getTaskService();
        //通过TaskService创建的TaskQuery查询待办任务
        List<Task> tasks = taskService.createTaskQuery().taskAssignee(assignee).list();
        if (CollectionUtil.isNotEmpty(tasks)){
            tasks.forEach(e->{
                System.out.println(e.getId());
                System.out.println(e.getName());
                System.out.println(e.getDelegationState());
                System.out.println(e.getAssignee());
                taskService.complete(e.getId());
            });
            //遍历提交
        }
    }

11.3流程相关的表

12.任务分配

12.1固定分配

12.2表达式分配

12.2.1值表达式

${任意占位符},在发起流程的时候添加一个Map<String,Object>对象来指定实际值

12.2.2方法表达式

搭配Spring使用,通过${bean名称.方法名()},使用时需要将类注入spring容器

12.3监听器分配

通过TaskListener实现,需要指定类和事件,并且在idea的插件中无法实现,需要通过流程设计器实现

13.身份信息

具体开发的时候使用较少,所以有需要的同学可以去单独了解一下

13.1候选人

13.2候选人组

13.3拾取归还

14.网关

14.0网关概念

14.0.1网关概念及示例bpmn文件

网关可以理解为'条件满足就执行某个流程',而给的流程变量则可以在任务审批的时候通过传入map来指定

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/processdef">
  <process id="gatway1" name="gatway1" isExecutable="true">
    <startEvent id="sid-f583878e-8f6b-468c-b238-ad6e01469cda"/>
    <exclusiveGateway id="sid-552ee69b-697c-4ec3-bf7b-39ac33069fca"/>
    <exclusiveGateway id="sid-cdc7f7d4-f108-4517-953a-e4e3158fa830"/>
    <userTask id="sid-e1442e5d-3d4c-4283-ab5d-100abe2546f9" name="小组长审批"/>
    <userTask id="sid-5c8a0518-7b4b-40c0-a8fd-b8fdb1a663b1" name="中组长审批"/>
    <userTask id="sid-5fe65f71-6c1c-419a-ba24-35a7862f875b" name="大组长审批"/>
    <sequenceFlow id="sid-0f164c3f-4334-492e-ad90-fc411ab098d0" sourceRef="sid-552ee69b-697c-4ec3-bf7b-39ac33069fca" targetRef="sid-e1442e5d-3d4c-4283-ab5d-100abe2546f9">
      <conditionExpression xsi:type="tFormalExpression">${day&gt;=0&amp;&amp;day&lt;3}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-48507e44-598b-4d80-b460-5aee74a34b2b" sourceRef="sid-552ee69b-697c-4ec3-bf7b-39ac33069fca" targetRef="sid-5c8a0518-7b4b-40c0-a8fd-b8fdb1a663b1">
      <conditionExpression xsi:type="tFormalExpression">${day&gt;=3&amp;&amp;day&lt;5}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-f4866a2f-72d2-44b0-9aaf-794898e8db31" sourceRef="sid-552ee69b-697c-4ec3-bf7b-39ac33069fca" targetRef="sid-5fe65f71-6c1c-419a-ba24-35a7862f875b">
      <conditionExpression xsi:type="tFormalExpression">${day&gt;5}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-f7d66fdf-7126-42fa-907f-04a0f924a412" sourceRef="sid-5c8a0518-7b4b-40c0-a8fd-b8fdb1a663b1" targetRef="sid-cdc7f7d4-f108-4517-953a-e4e3158fa830"/>
    <sequenceFlow id="sid-b2127989-164e-4871-9c8e-57cd170a08ac" sourceRef="sid-5fe65f71-6c1c-419a-ba24-35a7862f875b" targetRef="sid-cdc7f7d4-f108-4517-953a-e4e3158fa830"/>
    <sequenceFlow id="sid-ca68f7c7-eb84-478f-815e-6ff65051b547" sourceRef="sid-e1442e5d-3d4c-4283-ab5d-100abe2546f9" targetRef="sid-cdc7f7d4-f108-4517-953a-e4e3158fa830"/>
    <userTask id="sid-4f9af265-7ebe-4ea2-ae95-295789ab21c9" name="直属上司审批"/>
    <sequenceFlow id="sid-2de0a354-6988-43c7-be42-c2b47ed2306d" sourceRef="sid-cdc7f7d4-f108-4517-953a-e4e3158fa830" targetRef="sid-4f9af265-7ebe-4ea2-ae95-295789ab21c9">
      <conditionExpression xsi:type="tFormalExpression"/>
    </sequenceFlow>
    <userTask id="sid-4cae6048-58cf-4cc4-90b5-e5d8f9b53586" name="请假单提交"/>
    <sequenceFlow id="sid-05a6b735-c108-4d5b-9c28-f92a51ec8549" sourceRef="sid-f583878e-8f6b-468c-b238-ad6e01469cda" targetRef="sid-4cae6048-58cf-4cc4-90b5-e5d8f9b53586"/>
    <sequenceFlow id="sid-19c367e4-2740-4cfa-aa15-4cc3e473cb76" sourceRef="sid-4cae6048-58cf-4cc4-90b5-e5d8f9b53586" targetRef="sid-552ee69b-697c-4ec3-bf7b-39ac33069fca"/>
    <sequenceFlow id="sid-06dc5e8a-ecd1-4f27-a060-92d5b31e76d0" sourceRef="sid-4f9af265-7ebe-4ea2-ae95-295789ab21c9" targetRef="sid-1eae3969-d977-4a51-b496-ac4a788e4444"/>
    <userTask id="sid-6efaa987-0c31-4d5d-a4b1-77fb9a048a3b" name="人事经理审批"/>
    <userTask id="sid-2e00c88d-7965-4745-a526-f90d1ff033da" name="人事审批"/>
    <sequenceFlow id="sid-c72fefe7-6d5d-4506-9131-a69e45abdb73" sourceRef="sid-1eae3969-d977-4a51-b496-ac4a788e4444" targetRef="sid-2e00c88d-7965-4745-a526-f90d1ff033da">
      <conditionExpression xsi:type="tFormalExpression"/>
    </sequenceFlow>
    <sequenceFlow id="sid-5b160e8f-c44f-4ac9-bc4e-636a75133689" sourceRef="sid-1eae3969-d977-4a51-b496-ac4a788e4444" targetRef="sid-6efaa987-0c31-4d5d-a4b1-77fb9a048a3b">
      <conditionExpression xsi:type="tFormalExpression">${day&gt;3&amp;&amp;day&lt;5}</conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="sid-59932360-fa0b-4153-a2ce-0336eec94614" sourceRef="sid-2e00c88d-7965-4745-a526-f90d1ff033da" targetRef="sid-e235cb73-0d9f-4914-8f00-3d80d0c45c9e"/>
    <sequenceFlow id="sid-9075a6cf-ae75-4504-a02c-588cf9415216" sourceRef="sid-6efaa987-0c31-4d5d-a4b1-77fb9a048a3b" targetRef="sid-e235cb73-0d9f-4914-8f00-3d80d0c45c9e"/>
    <userTask id="sid-57f71275-7ba0-47ba-8658-2b8538a34fe9" name="总经理审批"/>
    <sequenceFlow id="sid-5dada524-66ed-415a-8dd8-5dfd4b7fdf5c" sourceRef="sid-e235cb73-0d9f-4914-8f00-3d80d0c45c9e" targetRef="sid-57f71275-7ba0-47ba-8658-2b8538a34fe9">
      <conditionExpression xsi:type="tFormalExpression"/>
    </sequenceFlow>
    <sequenceFlow id="sid-c84ea501-b5e3-4c27-851b-7617229ba0ab" sourceRef="sid-9e64cfa6-c4e9-4e59-b96a-2cf7d3af9d6f" targetRef="sid-4cae6048-58cf-4cc4-90b5-e5d8f9b53586">
      <conditionExpression xsi:type="tFormalExpression">${idea==0}</conditionExpression>
    </sequenceFlow>
    <exclusiveGateway id="sid-9e64cfa6-c4e9-4e59-b96a-2cf7d3af9d6f"/>
    <sequenceFlow id="sid-655f2946-1326-4cf5-87f9-8dc127ae480b" sourceRef="sid-57f71275-7ba0-47ba-8658-2b8538a34fe9" targetRef="sid-9e64cfa6-c4e9-4e59-b96a-2cf7d3af9d6f"/>
    <endEvent id="sid-9a61d77f-1e4e-43f0-8c01-833dab4c9590"/>
    <sequenceFlow id="sid-b2017542-d14d-45fe-9bcf-91909a3c0abb" sourceRef="sid-9e64cfa6-c4e9-4e59-b96a-2cf7d3af9d6f" targetRef="sid-9a61d77f-1e4e-43f0-8c01-833dab4c9590">
      <conditionExpression xsi:type="tFormalExpression">${idea==1}</conditionExpression>
    </sequenceFlow>
    <inclusiveGateway id="sid-1eae3969-d977-4a51-b496-ac4a788e4444"/>
    <inclusiveGateway id="sid-e235cb73-0d9f-4914-8f00-3d80d0c45c9e"/>
  </process>
  <bpmndi:BPMNDiagram id="BPMNDiagram_gatway1">
    <bpmndi:BPMNPlane bpmnElement="gatway1" id="BPMNPlane_gatway1">
      <bpmndi:BPMNShape id="shape-c9976f55-722e-46dd-ba42-8593623a7eae" bpmnElement="sid-f583878e-8f6b-468c-b238-ad6e01469cda">
        <omgdc:Bounds x="-205.0" y="0.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-103d2ad0-dd96-4085-877e-2b609e56eb6a" bpmnElement="sid-552ee69b-697c-4ec3-bf7b-39ac33069fca">
        <omgdc:Bounds x="45.0" y="-5.0" width="40.0" height="40.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="sid-c9850da3-4995-4d35-b142-f529a1e5241e" bpmnElement="sid-cdc7f7d4-f108-4517-953a-e4e3158fa830">
        <omgdc:Bounds x="321.27325" y="-5.0" width="40.0" height="40.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-89943eb5-ee2a-4964-ab3d-0bff61634314" bpmnElement="sid-e1442e5d-3d4c-4283-ab5d-100abe2546f9">
        <omgdc:Bounds x="150.00002" y="-155.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="sid-44095dc1-e7a8-48fd-ba61-51736aeaa880" bpmnElement="sid-5c8a0518-7b4b-40c0-a8fd-b8fdb1a663b1">
        <omgdc:Bounds x="150.00002" y="-25.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="sid-0446e25d-ef11-432d-9600-c9cd7f2a9e0c" bpmnElement="sid-5fe65f71-6c1c-419a-ba24-35a7862f875b">
        <omgdc:Bounds x="150.0" y="104.93238" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-3af5c865-b77a-440e-8fcc-8c45ae32f425" bpmnElement="sid-0f164c3f-4334-492e-ad90-fc411ab098d0">
        <omgdi:waypoint x="65.0" y="-5.0"/>
        <omgdi:waypoint x="150.00002" y="-95.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-8fecf7fc-318c-45ea-a5e5-3a62983a18ee" bpmnElement="sid-48507e44-598b-4d80-b460-5aee74a34b2b">
        <omgdi:waypoint x="85.0" y="15.0"/>
        <omgdi:waypoint x="150.00002" y="15.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-6946c366-e330-4022-ba72-7c6c773ebd60" bpmnElement="sid-f4866a2f-72d2-44b0-9aaf-794898e8db31">
        <omgdi:waypoint x="65.0" y="35.0"/>
        <omgdi:waypoint x="150.0" y="124.93237"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-aed09362-cc43-427e-b873-3f4f9f983086" bpmnElement="sid-f7d66fdf-7126-42fa-907f-04a0f924a412">
        <omgdi:waypoint x="250.00002" y="15.0"/>
        <omgdi:waypoint x="321.27325" y="15.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-57a71838-bbaf-4d0a-90ab-20c8d9adf15b" bpmnElement="sid-b2127989-164e-4871-9c8e-57cd170a08ac">
        <omgdi:waypoint x="250.0" y="124.93237"/>
        <omgdi:waypoint x="341.27325" y="35.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-5a2fcab7-b1ae-4717-9039-d59031316d0e" bpmnElement="sid-ca68f7c7-eb84-478f-815e-6ff65051b547">
        <omgdi:waypoint x="250.00002" y="-95.0"/>
        <omgdi:waypoint x="341.27325" y="-5.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="shape-2f3b8e37-4407-4d32-916c-63adeac18545" bpmnElement="sid-4f9af265-7ebe-4ea2-ae95-295789ab21c9">
        <omgdc:Bounds x="465.0" y="-25.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-5de83704-5882-4f33-aeeb-65f22bcd721b" bpmnElement="sid-2de0a354-6988-43c7-be42-c2b47ed2306d">
        <omgdi:waypoint x="361.27325" y="15.0"/>
        <omgdi:waypoint x="465.0" y="15.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="shape-9f276021-6ea4-4353-9782-6f50f88af4ff" bpmnElement="sid-4cae6048-58cf-4cc4-90b5-e5d8f9b53586">
        <omgdc:Bounds x="-120.0" y="-25.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-1cb2a5f4-1944-4091-9ee5-1b5fc4d6eb4f" bpmnElement="sid-05a6b735-c108-4d5b-9c28-f92a51ec8549">
        <omgdi:waypoint x="-175.0" y="15.0"/>
        <omgdi:waypoint x="-120.0" y="15.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-173392c8-bca9-4b10-a52e-fae97c79af1a" bpmnElement="sid-19c367e4-2740-4cfa-aa15-4cc3e473cb76">
        <omgdi:waypoint x="-20.0" y="15.0"/>
        <omgdi:waypoint x="45.0" y="15.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-40e7cb33-a5aa-4ca4-bd37-f1c5a2c12666" bpmnElement="sid-06dc5e8a-ecd1-4f27-a060-92d5b31e76d0">
        <omgdi:waypoint x="565.0" y="15.0"/>
        <omgdi:waypoint x="740.0" y="15.000001"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="shape-5390a6b3-508b-4338-8370-36a24f250b31" bpmnElement="sid-6efaa987-0c31-4d5d-a4b1-77fb9a048a3b">
        <omgdc:Bounds x="900.0" y="119.93236" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-91719f5f-8a3e-4f42-bd3f-65488f1d1924" bpmnElement="sid-2e00c88d-7965-4745-a526-f90d1ff033da">
        <omgdc:Bounds x="900.00006" y="-155.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-e0310fcf-507e-4fc6-ad15-d48807ae953a" bpmnElement="sid-c72fefe7-6d5d-4506-9131-a69e45abdb73">
        <omgdi:waypoint x="760.00006" y="-5.0"/>
        <omgdi:waypoint x="900.00006" y="-115.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-6d324844-733a-4221-aa8e-4bdeeadb7617" bpmnElement="sid-5b160e8f-c44f-4ac9-bc4e-636a75133689">
        <omgdi:waypoint x="760.00006" y="35.000004"/>
        <omgdi:waypoint x="900.0" y="139.93236"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-1bf73800-46b3-4171-8bda-529fc05f9703" bpmnElement="sid-59932360-fa0b-4153-a2ce-0336eec94614">
        <omgdi:waypoint x="1000.00006" y="-95.0"/>
        <omgdi:waypoint x="1110.0" y="0.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-f5626a3c-7ba6-47b6-b388-b6a75128ee26" bpmnElement="sid-9075a6cf-ae75-4504-a02c-588cf9415216">
        <omgdi:waypoint x="1000.0" y="139.93236"/>
        <omgdi:waypoint x="1110.0" y="40.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="shape-b5eee401-365e-4827-8e8e-6e41e319686b" bpmnElement="sid-57f71275-7ba0-47ba-8658-2b8538a34fe9">
        <omgdc:Bounds x="1280.0" y="-20.0" width="100.0" height="80.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-ad5a49be-9b65-4317-9472-5668c26eecfd" bpmnElement="sid-5dada524-66ed-415a-8dd8-5dfd4b7fdf5c">
        <omgdi:waypoint x="1130.0" y="20.0"/>
        <omgdi:waypoint x="1280.0" y="20.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge id="edge-a92b70f9-f8d1-45f5-89c7-acf22ace4657" bpmnElement="sid-c84ea501-b5e3-4c27-851b-7617229ba0ab">
        <omgdi:waypoint x="1595.0" y="-5.0"/>
        <omgdi:waypoint x="1590.0" y="-187.5"/>
        <omgdi:waypoint x="-69.99999" y="-187.5"/>
        <omgdi:waypoint x="-70.0" y="-25.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="shape-1475de2d-2c89-4f79-a8d0-182c1ef082ed" bpmnElement="sid-9e64cfa6-c4e9-4e59-b96a-2cf7d3af9d6f">
        <omgdc:Bounds x="1575.0" y="-5.0" width="40.0" height="40.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-58c8a9bd-ad7d-416f-af56-92a475518966" bpmnElement="sid-655f2946-1326-4cf5-87f9-8dc127ae480b">
        <omgdi:waypoint x="1380.0" y="20.0"/>
        <omgdi:waypoint x="1575.0" y="15.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="shape-e66925f5-b7dd-4c93-8248-db4b8a4905a4" bpmnElement="sid-9a61d77f-1e4e-43f0-8c01-833dab4c9590">
        <omgdc:Bounds x="1735.0" y="0.0" width="30.0" height="30.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge id="edge-62bed2fc-dd76-4dae-80f9-e0ed6bd859f6" bpmnElement="sid-b2017542-d14d-45fe-9bcf-91909a3c0abb">
        <omgdi:waypoint x="1615.0" y="15.0"/>
        <omgdi:waypoint x="1735.0" y="15.0"/>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNShape id="shape-eaa1517c-4069-4599-880e-a46715f9e6a6" bpmnElement="sid-1eae3969-d977-4a51-b496-ac4a788e4444">
        <omgdc:Bounds x="740.0" y="-5.0" width="40.0" height="40.0"/>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape id="shape-f7a46bbc-dd1c-4d66-9795-8cb95103fcd7" bpmnElement="sid-e235cb73-0d9f-4914-8f00-3d80d0c45c9e">
        <omgdc:Bounds x="1090.0" y="0.0" width="40.0" height="40.0"/>
      </bpmndi:BPMNShape>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

14.0.1审批流程时指定流程变量的值

14.1排他网关

排他网关好像一个人在分岔路口,只会选择一条线路前进,如果有多条连线符合条件,那就选择第一条在流程文件中出现的连线,如果没有符合条件的,就是用默认线路。

见上图,在第一个排他网关进行条件判断,会走满足条件的第一条路径汇聚到第二个排他网关继续执行

14.2并行网关

并行网关用于处理流程并发的场景,可以将流程分发到多个执行流程,也可以让多个执行流程合并为一个执行流(但不是必须一起使用),也就是说并行网关有两种行为,分叉和合并。

见上图,第一个并行网关会将一个流程拆分成为两个并行的流程,第二个并行网关会等待两个并行的流程都完成后汇聚在该网关后继续执行

14.3包容网关

排它网关在多个条件同时满足时,只会选择第一个满足条件的,并行网关是无条件的执行所有的执行流,而兼容网关可以看做是二者的结合,有几个满足条件的执行流,就执行几个满足条件的执行流必须有满足条件的执行流,不然会抛出异常

见上图

15.总结

该文总结了Activiti基本的使用,可以满足部分的简单的业务场景,留下 事件网关 未写入 需要的同学可以去自行了解。

  • 30
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值