Activiti7 之新手入门(三)

1 关于 Activiti 的一些思考(本文的重点)

  • activiti7 如何入门?
  • 业务参数如何传参和设值?
  • 排他网关和并行网关怎么使用?
  • 任务监听器如何使用?

2 了解Activiti

在这里插入图片描述

2.1 activiti.cfg.xml

activiti的引擎配置文件,包括:ProcessEngineConfiguration的定义、数据源定义、事务管理器等。此文件其实就是一个spring配置文件。

2.2 ProcessEngineConfiguration

通过 ProcessEngineConfiguration 可以创建工作流引擎 ProceccEngine,该类主要负责读取 activiti.cfg.xml 的配置。

public static ProcessEngineConfiguration createProcessEngineConfigurationFromResourceDefault() {
    
    
    return createProcessEngineConfigurationFromResource("activiti.cfg.xml", "processEngineConfiguration");
}

2.3 ProcessEngine

相当于一个门面接口,通过ProcessEngineConfiguration创建processEngine,通过ProcessEngine创建各个service接口,具体代码逻辑由 ProcessEngineImpl.class 实现。

public interface ProcessEngine {
    
    
    String VERSION = "7.0.0.0";

    String getName();

    void close();

    RepositoryService getRepositoryService();

    RuntimeService getRuntimeService();

    TaskService getTaskService();

    HistoryService getHistoryService();

    ManagementService getManagementService();

    DynamicBpmnService getDynamicBpmnService();

    ProcessEngineConfiguration getProcessEngineConfiguration();
}

2.4 Service 核心管理类

  • RepositoryService:是activiti的资源管理类,提供了管理和控制流程发布包和流程定义的操作。
  • RuntimeService:Activiti的流程运行管理类。可以从这个服务类中获取很多关于流程执行相关的信息
  • TaskService:Activiti的任务管理类。可以从这个类中获取任务的信息
  • HistoryService:Activiti的历史管理类,可以查询历史信息,执行流程时,引擎会保存很多数据(根据配置),比如流程实例启动时间,任务的参与者, 完成任务的时间,每个流程实例的执行路径,等等。此服务主要通过查询功能来获得这些数据。
  • ManagementService:Activiti的引擎管理类,提供了对 Activiti 流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用,主要用于Activiti 系统的日常维护
  • FormService :弃用,该管理类不符合 activiti 的设计理念。
  • IdentityService :认证管理类,暂时不用。

2.5 数据库表

Activiti 流程框架有一套自己的数据库表,一共25张表,通过这些表从而实现流程管理。

这是官方数据库表的解释,文档适用于Activiti5~6:Activiti 数据库表结构

  • ACT_RE_ : 'RE’表示repository,仓库的意思。 这个前缀的表包含了流程定义和流程静态资源
  • ACT_RU_ :RU代表runtime,运行时的意思。这些是包含流程实例,用户任务,变量,作业等的运行时数据的运行时表。Activiti仅在流程实例执行期间存储运行时数据,并在进程实例结束时删除记录。这使得运行时间表保持不间断的快速。
  • ACT_ID_ :ID代表identity,身份识别。这些表包含身份信息,如用户,组等。
  • ACT_HI_ :HI代表history。这些是包含历史数据的表,例如过去的流程实例,变量,任务等。
  • ACT_GE_ :general数据,用于各种用例。

2.6

3 入门配置工作

3.1 建个数据库,名字叫:activiti

在这里插入图片描述

3.2 创建一个 maven 项目,加入依赖

  <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>
    <dependency>
      <groupId>org.activiti</groupId>
      <artifactId>activiti-engine</artifactId>
      <version>${activiti.version}</version>
    </dependency>
    <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>
    <!-- activiti 云支持 -->
    <dependency>
      <groupId>org.activiti.cloud</groupId>
      <artifactId>activiti-cloud-services-api</artifactId>
      <version>7.0.0.Beta1</version>
      <exclusions>
        <exclusion><!-- 排除activiti的mybatis,避免和外面的mybatis-plus冲突 -->
          <!-- 重点坑,不然启动项目会报错mybatisplus缺少类   -->
          <artifactId>mybatis</artifactId>
          <groupId>org.mybatis</groupId>
        </exclusion>
      </exclusions>
    </dependency>
    <!-- mysql驱动 -->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.27</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>
  </dependencies>

3.3 Activiti 配置文件 activiti.cfg.xml

在这里插入图片描述

  <!--数据库连接池方式配置-->
  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://192.168.1.181/activiti?useSSL=false"/>
    <property name="username" value="root"/>
    <property name="password" value="test@xhkj"/>

    <property name="maxActive" value="3"/>
    <property name="maxIdle" value="1"/>

  </bean>
  <!--同样, 在默认方式下bean的id固定为 processEngineConfiguration-->
  <bean id="processEngineConfiguration"
        class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
    <!--引入上面配置好的 链接池-->
    <property name="dataSource" ref="dataSource"/>
    <property name="databaseSchemaUpdate" value="true"/>
  </bean>

4 启动 Activiti

直接见代码,相关注释,代码里都很详细

package com.activiti.test;

import org.activiti.engine.*;
import org.junit.Test;

public class ActivitiCreate {
    
    

    /**
     * 使用activiti提供的默认方式来创建mysql的表
     */
    @Test
    public void testCreateDbTable1() {
    
    
        // 需要使用avtiviti提供的工具类 ProcessEngines ,使用方法getDefaultProcessEngine
        // getDefaultProcessEngine会默认从resources下读取名字为activiti.cfg.xml的文件
        // 创建processEngine时,就会创建mysql的表
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        System.out.println(processEngine);
    }

    @Test
    public void testGetService() {
    
    
        //获取各个service实例
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        RepositoryService repositoryService = processEngine.getRepositoryService();
        RuntimeService runtimeService = processEngine.getRuntimeService();
        TaskService taskService = processEngine.getTaskService();
        HistoryService historyService = processEngine.getHistoryService();
    }

    /**
     * 一般创建方式
     */
    @Test
    public void testCreateDbTable2() {
    
    
		// ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
        // 配置文件的名字可以自定义,bean的名字也可以自定义
        ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml","processEngineConfiguration");
        // 获取流程引擎对象
        ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
    }
}

5 简单运用 Activiti

直接见代码,相关注释,代码里都很详细

package com.activiti.test;

import org.activiti.engine.*;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.util.List;


public class ActivitiDemo {
    
    

    /**
     * 流程部署
     * `act_re_deployment`   流程部署表,每部署一次会增加一条记录
     * `act_re_procdef`      流程定义表,张三会申请出差流程,李四也会申请出差流程,每个人申请都会增加一条记录
     * act_re_deployment与act_re_procdef是一对多关系
     * `act_ge_bytearray`    流程资源表,每个资源都会增加一条记录
     */
    @Test
    public void testDeployment() throws FileNotFoundException {
    
    

        String evectionBpmnPath = ActivitiDemo.class.getClassLoader().getResource("bpmn/evection.bpmn").getFile();
        File evectionBpmnFile = new File(evectionBpmnPath);
        InputStream evectionBpmnIs = new FileInputStream(evectionBpmnFile);

        String evectionPngPath = ActivitiDemo.class.getClassLoader().getResource("bpmn/evection.png").getFile();
        File evectionPngFile = new File(evectionPngPath);
        InputStream evectionPngIs = new FileInputStream(evectionPngFile);

        // 1、创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

        // 2、获取RepositoryService
        RepositoryService repositoryService = processEngine.getRepositoryService();

        // 3、使用service进行流程的部署,定义一个流程的名字,把bpmn和png部署到数据中
        Deployment deploy = repositoryService.createDeployment()
                .name("出差申请流程")
                .addInputStream("evection.bpmn", evectionBpmnIs)
                .addInputStream("evection.png", evectionPngIs)
                .deploy();

        // 4、输出部署信息
        System.out.println("流程部署id=" + deploy.getId());
        System.out.println("流程部署名字=" + deploy.getName());
    }

    /**
     * 启动流程实例
     * `act_hi_actinst`    流程实例执行历史信息
     * `act_hi_identitylink` 流程参与用户的历史信息
     * `act_hi_procinst`     流程实例的历史信息
     * `act_hi_taskinst`     流程任务的历史信息
     * `act_ru_execution`    流程执行信息
     * `act_ru_identitylink`  流程的正在参与用户信息
     * `act_ru_task`         流程当前任务信息
     */
    @Test
    public void testStartProcess() {
    
    
        // 1、创建ProcessEngine
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2、获取RunTimeService
        RuntimeService runtimeService = processEngine.getRuntimeService();
        // 3、根据流程定义的id启动流程
        ProcessInstance instance = runtimeService.startProcessInstanceByKey("myEvection");
        // 4、输出内容
        System.out.println("流程定义ID:" + instance.getProcessDefinitionId());
        System.out.println("流程实例ID:" + instance.getId());
        System.out.println("当前活动的ID:" + instance.getActivityId());
    }

    /**
     * 查询个人待执行的任务
     */
    @Test
    public void testFindPersonalTaskList() {
    
    
        // 1、获取流程引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 2、获取taskService
        TaskService taskService = processEngine.getTaskService();
        // 3、根据流程key 和 任务的负责人 查询任务
        List<Task> taskList = taskService.createTaskQuery()
                .processDefinitionKey("myEvection") //流程Key
                .taskAssignee("李四")  //要查询的负责人
                .list();
        // 4、输出
        for (Task task : taskList) {
    
    
            System.out.println("流程实例id=" + task.getProcessInstanceId());
            System.out.println("任务Id=" + task.getId());
            System.out.println("任务负责人=" + task.getAssignee());
            System.out.println("任务名称=" + task.getName());
        }
    }

    /**
     * 完成个人任务 : 创建出差申请
     * `act_ru_task` 这里的 '创建出差申请' 会变为 '经理审批'
     * 也就是也是下一个任务:  经理审批
     * `act_hi_taskinst` 这里的'创建出差申请'这条记录会有开始时间和结束时间
     * 然后还会增加一条记录 '经理审批'
     */
    @Test
    public void completeTask() {
    
    
        // 获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取操作任务的服务 TaskService
        TaskService taskService = processEngine.getTaskService();
        // 完成任务,参数:任务id,完成 '张三' 的任务
        taskService.complete("2505");
    }

    // 改造: 不把id写死,通过查询,然后执行任务
    // 完成经理'李四'的任务
    @Test
    public void completeTask2() {
    
    
        // 获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取操作任务的服务 TaskService
        TaskService taskService = processEngine.getTaskService();
        // 完成 经理 '李四' 的任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myEvection")
                .taskAssignee("李四")
                .singleResult();

        System.out.println("流程实例id=" + task.getProcessInstanceId());
        System.out.println("任务Id=" + task.getId());
        System.out.println("任务负责人=" + task.getAssignee());
        System.out.println("任务名称=" + task.getName());

        taskService.complete(task.getId());
    }

    // 完成总经理'老马'的任务
    @Test
    public void completeTask3() {
    
    
        // 获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取操作任务的服务 TaskService
        TaskService taskService = processEngine.getTaskService();
        // 完成 经理 '李四' 的任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myEvection")
                .taskAssignee("老马")
                .singleResult();

        System.out.println("流程实例id=" + task.getProcessInstanceId());
        System.out.println("任务Id=" + task.getId());
        System.out.println("任务负责人=" + task.getAssignee());
        System.out.println("任务名称=" + task.getName());

        taskService.complete(task.getId());
    }

    // 完成财务'小王'的任务
    @Test
    public void completeTask4() {
    
    
        // 获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取操作任务的服务 TaskService
        TaskService taskService = processEngine.getTaskService();
        // 完成 经理 '李四' 的任务
        Task task = taskService.createTaskQuery()
                .processDefinitionKey("myEvection")
                .taskAssignee("小王")
                .singleResult();

        System.out.println("流程实例id=" + task.getProcessInstanceId());
        System.out.println("任务Id=" + task.getId());
        System.out.println("任务负责人=" + task.getAssignee());
        System.out.println("任务名称=" + task.getName());

        taskService.complete(task.getId());
    }

    // 如果一个流程中有多个任务,可以用list
    @Test
    public void completeTask5() {
    
    
        // 获取引擎
        ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
        // 获取操作任务的服务 TaskService
        TaskService taskService = processEngine.getTaskService();
        // 完成 经理 '李四' 的任务
        List<Task> tasks = taskService.createTaskQuery()
                .processDefinitionKey("myEvection")
                .taskAssignee("李四")
                .list();  // 多个任务,用list

        for (Task task : tasks) {
    
    
            if (true) {
    
    
                // 判断是哪任务
                System.out.println("流程实例id=" + task.getProcessInstanceId());
                System.out.println("任务Id=" + task.getId());
                System.out.println("任务负责人=" + task.getAssignee());
                System.out.println("任务名称=" + task.getName());
                taskService.complete(task.getId());
            }
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_23845083/article/details/131292627