springBoot2.1.5集成Activiti7.1.24

@高效码农  May 25, 2019

一、使用IDEA快速搭建SpringBoot项目

请在百度中自行搜索
或者直接跳转:https://blog.csdn.net/frank_come/article/details/80824968

二、设置pom.xml

pom文件配置如下:

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.5.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>activiti7</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>activiti7</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <activiti-dependencies.version>7.1.24</activiti-dependencies.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.activiti.dependencies</groupId>
                <artifactId>activiti-dependencies</artifactId>
                <version>${activiti-dependencies.version}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.activiti</groupId>
            <artifactId>activiti-spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- 阿里 druid 数据源 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.1.16</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

    <repositories>
        <repository>
            <id>alfresco</id>
            <name>Activiti Releases</name>
            <url>https://artifacts.alfresco.com/nexus/content/repositories/activiti-releases/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
        </repository>
    </repositories>


</project>

三、设计流程图

myProcess.png
流程图代码

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" 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" xmlns:tns="EmployeeAskForLeave" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:yaoqiang="http://bpmn.sourceforge.net" expressionLanguage="http://www.w3.org/1999/XPath" id="_1558504900768" name="" targetNamespace="EmployeeAskForLeave" typeLanguage="http://www.w3.org/2001/XMLSchema">
  <process id="myProcess" isClosed="false" isExecutable="true" name="员工请假流程" processType="None">
    <extensionElements>
      <yaoqiang:description/>
      <yaoqiang:pageFormat height="841.8897637795276" imageableHeight="831.8897637795276" imageableWidth="588.1102362204724" imageableX="5.0" imageableY="5.0" orientation="0" width="598.1102362204724"/>
      <yaoqiang:page background="#FFFFFF" horizontalCount="1" verticalCount="1"/>
    </extensionElements>
    <startEvent id="startevent1" isInterrupting="true" name="Start" parallelMultiple="false"/>
    <endEvent id="endevent1" name="End"/>
    <sequenceFlow id="flow1" sourceRef="startevent1" targetRef="usertask1"/>
    <userTask activiti:assignee="${userKey}" activiti:exclusive="true" completionQuantity="1" id="usertask1" implementation="##unspecified" isForCompensation="false" name="填写请假申请" startQuantity="1"/>
    <exclusiveGateway gatewayDirection="Unspecified" id="exclusivegateway1" name="请假时间判断(排他网关)"/>
    <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="exclusivegateway1"/>
    <userTask activiti:candidateGroups="HR" activiti:exclusive="true" completionQuantity="1" id="usertask2" implementation="##unspecified" isForCompensation="false" name="经理审批" startQuantity="1"/>
    <userTask activiti:candidateGroups="ZJ" activiti:exclusive="true" completionQuantity="1" id="usertask3" implementation="##unspecified" isForCompensation="false" name="总监审批" startQuantity="1"/>
    <sequenceFlow id="flow3" name="小于等于3夿" sourceRef="exclusivegateway1" targetRef="usertask2">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${days<=3}]]></conditionExpression>
    </sequenceFlow>
    <sequenceFlow id="flow4" name="大于3夿" sourceRef="exclusivegateway1" targetRef="usertask3">
      <conditionExpression xsi:type="tFormalExpression"><![CDATA[${days>3}]]></conditionExpression>
    </sequenceFlow>
    <exclusiveGateway gatewayDirection="Unspecified" id="exclusivegateway2" name="请假时间判断(排他网关)"/>
    <sequenceFlow id="flow5" sourceRef="usertask2" targetRef="exclusivegateway2"/>
    <sequenceFlow id="flow6" sourceRef="usertask3" targetRef="exclusivegateway2"/>
    <sequenceFlow id="flow7" sourceRef="exclusivegateway2" targetRef="endevent1"/>
  </process>
  <bpmndi:BPMNDiagram documentation="background=#3C3F41;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="Untitled Diagram">
    <bpmndi:BPMNPlane bpmnElement="myProcess">
      <bpmndi:BPMNShape bpmnElement="startevent1" id="Shape-startevent1">
        <omgdc:Bounds height="32.0" width="32.0" x="200.0" y="220.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="endevent1" id="Shape-endevent1">
        <omgdc:Bounds height="32.0" width="32.0" x="1040.0" y="220.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask1" id="Shape-usertask1">
        <omgdc:Bounds height="55.0" width="105.0" x="320.0" y="210.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway1" id="Shape-exclusivegateway1" isMarkerVisible="true">
        <omgdc:Bounds height="32.0" width="32.0" x="470.0" y="217.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask2" id="Shape-usertask2">
        <omgdc:Bounds height="55.0" width="105.0" x="650.0" y="130.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="usertask3" id="Shape-usertask3">
        <omgdc:Bounds height="55.0" width="105.0" x="650.0" y="270.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="55.0" width="105.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNShape bpmnElement="exclusivegateway2" id="Shape-exclusivegateway2" isMarkerVisible="true">
        <omgdc:Bounds height="32.0" width="32.0" x="920.0" y="217.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNShape>
      <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1" sourceElement="startevent1" targetElement="usertask1">
        <omgdi:waypoint x="232.0" y="236.0"/>
        <omgdi:waypoint x="320.0" y="237.5"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="21.02" width="6.0" x="273.0" y="226.07"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2" sourceElement="usertask1" targetElement="exclusivegateway1">
        <omgdi:waypoint x="425.0" y="237.5"/>
        <omgdi:waypoint x="470.0" y="233.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="21.02" width="6.0" x="444.5" y="227.16"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3" sourceElement="exclusivegateway1" targetElement="usertask2">
        <omgdi:waypoint x="490.0" y="221.0"/>
        <omgdi:waypoint x="490.0" y="157.0"/>
        <omgdi:waypoint x="650.0" y="157.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="37.02" width="67.0" x="505.92" y="138.49"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4" sourceElement="exclusivegateway1" targetElement="usertask3">
        <omgdi:waypoint x="490.0" y="245.0"/>
        <omgdi:waypoint x="490.0" y="297.0"/>
        <omgdi:waypoint x="650.0" y="297.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="37.02" width="56.0" x="522.58" y="278.49"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow5" id="BPMNEdge_flow5" sourceElement="usertask2" targetElement="exclusivegateway2">
        <omgdi:waypoint x="755.0" y="157.0"/>
        <omgdi:waypoint x="940.0" y="157.0"/>
        <omgdi:waypoint x="940.0" y="221.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="21.02" width="6.0" x="874.92" y="146.49"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow6" id="BPMNEdge_flow6" sourceElement="usertask3" targetElement="exclusivegateway2">
        <omgdi:waypoint x="755.0" y="297.0"/>
        <omgdi:waypoint x="940.0" y="297.0"/>
        <omgdi:waypoint x="940.0" y="245.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="21.02" width="6.0" x="863.75" y="286.49"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
      <bpmndi:BPMNEdge bpmnElement="flow7" id="BPMNEdge_flow7" sourceElement="exclusivegateway2" targetElement="endevent1">
        <omgdi:waypoint x="952.0" y="233.0"/>
        <omgdi:waypoint x="1040.0" y="236.0"/>
        <bpmndi:BPMNLabel>
          <omgdc:Bounds height="21.02" width="6.0" x="998.0" y="226.74"/>
        </bpmndi:BPMNLabel>
      </bpmndi:BPMNEdge>
    </bpmndi:BPMNPlane>
  </bpmndi:BPMNDiagram>
</definitions>

四、配置文件


spring:
    #Activiti property configuration
    activiti:
        database-schema-update: true
        history-level: full
        db-history-used: true

    datasource:
        url: jdbc:mysql://localhost:3306/activiti7?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC&nullCatalogMeansCurrent=true
        username: root
        password: root
        driver-class-name: com.mysql.cj.jdbc.Driver
        type: com.alibaba.druid.pool.DruidDataSource

        initialization-mode: always

        initialSize: 5
        minIdle: 5
        maxActive: 20
        maxWait: 60000
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: SELECT 1 FROM DUAL
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        filters: stat,wall,log4j
        maxPoolPreparedStatementPerConnectionSize: 20
        useGlobalDataSourceStat: true
        connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500


logging:
    level:
        com.ascendant: debug
    pattern:
        console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %clr(-%5p)  %clr(${PID:- }){magenta} --- %clr([%15.15t]){faint} %highlight(%-80.80logger{300}){cyan} %clr(:) %m %n%wEx"

五、SpringBootTest测试

部署流程定义

    @Test
    public void prepare() {
        Deployment deployment = repositoryService.createDeployment()//创建一个部署对象
                .name("请假流程")
                .addClasspathResource("processes/myProcess.bpmn")
                .addClasspathResource("processes/myProcess.png")
                .deploy();
        System.out.println("部署ID:"+deployment.getId());
        System.out.println("部署名称:"+deployment.getName());
    }

启动流程实例分配任务给个人

    /**启动流程实例分配任务给个人*/
    @Test
    public void start() {

        String userKey="PTM";//脑补一下这个是从前台传过来的数据
        String processDefinitionKey ="myProcess";//每一个流程有对应的一个key这个是某一个流程内固定的写在bpmn内的
        HashMap<String, Object> variables=new HashMap<>();
        variables.put("userKey", userKey);//userKey在上文的流程变量中指定了
        variables.put("day", 2);
        variables.put("users", "a");

        ProcessInstance instance = runtimeService
                .startProcessInstanceByKey(processDefinitionKey,variables);

        System.out.println("流程实例ID:"+instance.getId());
        System.out.println("流程定义ID:"+instance.getProcessDefinitionId());
    }

查询当前人的个人任务

/**查询当前人的个人任务*/
    @Test
    public void findTask(){
        String assignee = "a";
        List<Task> list = taskService.createTaskQuery()//创建任务查询对象
                .taskAssignee(assignee)//指定个人任务查询
                .list();
        if(list!=null && list.size()>0){
            for(Task task:list){
                System.out.println("任务ID:"+task.getId());
                System.out.println("任务名称:"+task.getName());
                System.out.println("任务的创建时间:"+task.getCreateTime());
                System.out.println("任务的办理人:"+task.getAssignee());
                System.out.println("流程实例ID:"+task.getProcessInstanceId());
                System.out.println("执行对象ID:"+task.getExecutionId());
                System.out.println("流程定义ID:"+task.getProcessDefinitionId());
                System.out.println("getOwner:"+task.getOwner());
                System.out.println("getCategory:"+task.getCategory());
                System.out.println("getDescription:"+task.getDescription());
                System.out.println("getFormKey:"+task.getFormKey());
                Map<String, Object> map = task.getProcessVariables();
                for (Map.Entry<String, Object> m : map.entrySet()) {
                    System.out.println("key:" + m.getKey() + " value:" + m.getValue());
                }
                for (Map.Entry<String, Object> m : task.getTaskLocalVariables().entrySet()) {
                    System.out.println("key:" + m.getKey() + " value:" + m.getValue());
                }

            }
        }
    }

完成任务

    @Test
    public void completeTask(){
        //任务ID
        String taskId = "6825fdf2-7e04-11e9-a0c6-408d5ccf513c";

        HashMap<String, Object> variables=new HashMap<>();
        variables.put("days", 1);//userKey在上文的流程变量中指定了

        taskService.complete(taskId,variables);
        System.out.println("完成任务:任务ID:"+taskId);
    }

查询当前人的组任务

    /**查询当前人的组任务*/
    @Test
    public void findTaskGroup(){

        String assignee = "a";
        List<Task> list = taskService.createTaskQuery()//创建任务查询对象
//                .taskCandidateUser("ZJ")//指定组任务查询
                .taskAssignee(assignee)
                .list();
        String taskid ="";
        String instanceId ="";
        if(list!=null && list.size()>0){
            for(Task task:list){
                System.out.println("任务ID:"+task.getId());
                System.out.println("任务名称:"+task.getName());
                System.out.println("任务的创建时间:"+task.getCreateTime());
                System.out.println("任务的办理人:"+task.getAssignee());
                System.out.println("流程实例ID:"+task.getProcessInstanceId());
                System.out.println("执行对象ID:"+task.getExecutionId());
                System.out.println("流程定义ID:"+task.getProcessDefinitionId());
            }
        }
    }

参考网址:
https://blog.csdn.net/qq_40451631/article/details/84937251#21_ProcessEngine_5
https://blog.csdn.net/pan1458689676?t=1
https://salaboy.com/2018/08/13/getting-started-with-activiti-core-7-0-0-beta1/



评论已关闭

  1. 范德萨

    啦啦啦

  2. 程序员

    你好,大牛,请教一下,假如是想通过api上传的方式(而不是读取processes目录下的bpmn文件)去部署流程,应该怎么操作?

  3. 2

    请问本教程里面的画流程图插件是什么呢

  4. 1

    dd

  5. pippen

    为什么我下载不下来jar包

  6. 如果有完整代码就更好了

    1. @poorguy

      完整代码地址:https://github.com/xugj-gits/SpringBoot2_Activiti7

  7. 集成activiti7之后,ProcessDeployedEventImpl 对象很多导致内存溢出,请问有遇到类似问题吗

    1. @牛

      报错信息?