Premiers pas avec Activiti7 (3)

1 Quelques réflexions sur Activiti (le focus de cet article)

  • Comment démarrer avec activiti7 ?
  • Comment passer des paramètres et définir des valeurs pour les paramètres métier ?
  • Comment utiliser la passerelle exclusive et la passerelle parallèle ?
  • Comment utiliser l'écouteur de tâches ?

2 Comprendre les activités

insérez la description de l'image ici

2.1 activiti.cfg.xml

Fichier de configuration du moteur d'Activiti, comprenant : la définition de ProcessEngineConfiguration, la définition de la source de données, le gestionnaire de transactions, etc. Ce fichier est en fait un fichier de configuration Spring.

2.2 Configuration du moteur de processus

Le moteur de workflow ProceccEngine peut être créé via ProcessEngineConfiguration, qui est principalement responsable de la lecture de la configuration de activiti.cfg.xml.

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

2.3 ProcessEngine

Cela équivaut à une interface de façade. ProcessEngine est créé via ProcessEngineConfiguration et chaque interface de service est créée via ProcessEngine. La logique de code spécifique est implémentée par 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 Classe de gestion de base de service

  • RepositoryService : il s'agit de la classe de gestion des ressources d'activiti, qui fournit des opérations de gestion et de contrôle des packages de publication de processus et des définitions de processus .
  • RuntimeService : la classe de gestion des opérations de processus d'Activiti. Vous pouvez obtenir beaucoup d'informations sur l'exécution des processus à partir de cette classe de service .
  • TaskService : la classe de gestion des tâches d'Activiti. Les informations sur les tâches peuvent être obtenues à partir de cette classe .
  • HistoryService : la classe de gestion de l'historique d'Activiti, qui peut interroger les informations historiques . Lors de l'exécution d'un processus, le moteur enregistre de nombreuses données (selon la configuration), telles que l'heure de début de l'instance de processus, les participants de la tâche, l'heure pour terminer la tâche, et le chemin d'exécution de chaque instance de processus, etc. Ce service obtient ces données principalement via la fonction de requête.
  • ManagementService : la classe de gestion du moteur d'Activiti fournit des fonctions de gestion et de maintenance pour le moteur de processus Activiti. Ces fonctions ne sont pas utilisées dans les applications pilotées par le workflow et sont principalement utilisées pour la maintenance quotidienne du système Activiti .
  • FormService : Obsolète, cette classe de gestion n'est pas conforme au concept de conception des activités.
  • IdentityService : classe de gestion d'authentification, non utilisée pour l'instant.

2.5 Tableaux de la base de données

Le cadre de processus Activiti possède son propre ensemble de tables de base de données, un total de 25 tables, à travers lesquelles la gestion des processus est réalisée.

Voici l'explication de la table de base de données officielle, le document s'applique à Activiti5~6 : structure de la table de base de données Activiti

  • ACT_RE_ : 'RE' signifie référentiel, c'est-à-dire entrepôt. La table avec ce préfixe contient la définition du processus et les ressources statiques du processus
  • ACT_RU_ : RU signifie runtime, ce qui signifie runtime. Ce sont des tables d'exécution qui contiennent des données d'exécution pour les instances de processus, les tâches utilisateur, les variables, les travaux, etc. Activiti stocke uniquement les données d'exécution pendant l'exécution de l'instance de processus et supprime les enregistrements lorsque l'instance de processus se termine. Cela permet de maintenir les horaires d'exécution sans interruption rapide.
  • ACT_ID_ : ID signifie identité, identification. Ces tables contiennent des informations d'identité telles que les utilisateurs, les groupes, etc.
  • ACT_HI_ : HI signifie histoire. Ce sont des tables contenant des données historiques telles que des instances de processus passées, des variables, des tâches, etc.
  • ACT_GE_ : données générales, utilisées pour divers cas d'utilisation.

2.6

3 Mise en route du travail de configuration

3.1 Créer une base de données nommée : activiti

insérez la description de l'image ici

3.2 Créer un projet maven et ajouter des dépendances

  <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 Fichier de configuration des activités activiti.cfg.xml

insérez la description de l'image ici

  <!--数据库连接池方式配置-->
  <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 Démarrer l'activité

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

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 Utilisation simple d'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