简单的activiti5流程框架代码实现:

来源:互联网 发布:约维蒂奇 知乎 编辑:程序博客网 时间:2024/05/14 06:10

简单的activiti5流程框架代码实现:
流程图:简单流程
第一步:安装插件activiti-designer-5.18,要用jdk1.5以后的版本
第二步:创建Spring-boot工程,选择activiti组件
第三步:导入相关jar包,并编写相关配置
添加依赖关系

        <dependency>            <groupId>org.mybatis.spring.boot</groupId>            <artifactId>mybatis-spring-boot-starter</artifactId>            <version>1.1.1</version>        </dependency>        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>        </dependency>        <!-- 数据库连接池 -->        <dependency>            <groupId>com.alibaba</groupId>            <artifactId>druid</artifactId>            <version>1.0.5</version>        </dependency>

编写application.yml配置文件

---  spring:   datasource:      name: mydb      type: com.alibaba.druid.pool.DruidDataSource      url: jdbc:mysql://127.0.0.1:3306/test      username: root      password: root      driver-class-name: com.mysql.jdbc.Driver   

第四步:测试

@Test    public void allStep() {        // 部署        repositoryService            .createDeployment()            .addClasspathResource("MyProcess2.bpmn")            .deploy();        // 获取流程定义ID        ProcessDefinition pd =          repositoryService            .createProcessDefinitionQuery()            .processDefinitionKey("myProcess")            .latestVersion()            .singleResult();        // 启动        ProcessInstance pi = runtimeService.startProcessInstanceById(pd.getId());        // 完成任务        TaskQuery query = taskService.createTaskQuery();        List<Task> ts = query.taskAssignee("zhangsan").list();        for ( Task t : ts ) {            System.out.println( "zhangsan完成的任务 =" + t.getName() );            taskService.complete(t.getId());        }        // 历史查询        HistoricProcessInstanceQuery hpiQuery =            historyService.createHistoricProcessInstanceQuery();        HistoricProcessInstance hpi =            hpiQuery.processInstanceId(pi.getId()).finished().singleResult();        System.out.println("流程【"+pi.getId()+"】是否结束 = " + (hpi != null));        query = taskService.createTaskQuery();        ts = query.taskAssignee("lisi").list();        for ( Task t : ts ) {            System.out.println( "lisi完成的任务 =" + t.getName() );            taskService.complete(t.getId());        }        hpiQuery =            historyService.createHistoricProcessInstanceQuery();        hpi =            hpiQuery.processInstanceId(pi.getId()).finished().singleResult();        System.out.println("流程【"+pi.getId()+"】是否结束 = " + (hpi != null));    }

简简单单的一个流程框架就算入门了。
测试遇到的问题:

@Test    public void contextLoads() {        // ProcessEngineImpl        // 1)依赖jar包优先级(将mybatis的依赖关系放置在前面)        // 2) 新版本的activiti框架需要在classpath中增加processes文件夹。        //System.out.println( "processEngine = " + processEngine );        //RepositoryService repositoryService = processEngine.getRepositoryService();        System.out.println(repositoryService);    }

相关知识:
ProcessEngine这个类是Activiti5的核心,所有的服务都需要通过ProcessEngine来创建,该类是线程安全的
Activiti5的持久化层采用的是Mybatis,这样移植性好
Activiti5主要包括7个Service,这些Service都是通过ProcessEngine创建
repositoryService(持久化服务)
runtimeService(运行时服务)
formService(表单服务)
identityService(身份信息)
taskService(任务服务)
historyService(历史信息)
managementService(管理定时任务)

Activiti使用到的表都是ACT_开头的。

ACT_RE_*: ‘RE’表示repository(存储),RepositoryService接口所操作的表。带此前缀的表包含的是静态信息,如,流程定义,流程的资源(图片,规则等)。ACT_RU_*: ‘RU’表示runtime,运行时表-RuntimeService。这是运行时的表存储着流程变量,用户任务,变量,职责(job)等运行时的数据。Activiti只存储实例执行期间的运行时数据,当流程实例结束时,将删除这些记录。这就保证了这些运行时的表小且快。ACT_ID_*: ’ID’表示identity (组织机构),IdentityService接口所操作的表。用户记录,流程中使用到的用户和组。这些表包含标识的信息,如用户,用户组,等等。ACT_HI_*: ’HI’表示history,历史数据表,HistoryService。就是这些表包含着流程执行的历史相关数据,如结束的流程实例,变量,任务,等等ACT_GE_*: 全局通用数据及设置(general),各种情况都使用的数据。

act_ge_bytearray二进制数据表
act_ge_property属性数据表存储整个流程引擎级别的数据,初始化表结构时,会默认插入三条记录,
act_hi_actinst历史节点表
act_hi_attachment历史附件表
act_hi_comment历史意见表
act_hi_identitylink历史流程人员表
act_hi_detail历史详情表,提供历史变量的查询
act_hi_procinst历史流程实例表
act_hi_taskinst历史任务实例表
act_hi_varinst历史变量表
act_id_group用户组信息表
act_id_info用户扩展信息表
act_id_membership用户与用户组对应信息表
act_id_user用户信息表
act_re_deployment部署信息表
act_re_model流程设计模型部署表
act_re_procdef流程定义数据表
act_ru_event_subscr throwEvent、catchEvent时间监听信息表
act_ru_execution运行时流程执行实例表
act_ru_identitylink运行时流程人员表,主要存储任务节点与参与者的相关信息
act_ru_job运行时定时任务数据表
act_ru_task运行时任务节点表
act_ru_variable运行时流程变量数据表

附上完整的测试类:

package com.atguigu.atcrowdfunding.member;import java.util.HashMap;import java.util.List;import java.util.Map;import org.activiti.engine.HistoryService;import org.activiti.engine.ProcessEngine;import org.activiti.engine.RepositoryService;import org.activiti.engine.RuntimeService;import org.activiti.engine.TaskService;import org.activiti.engine.history.HistoricProcessInstance;import org.activiti.engine.history.HistoricProcessInstanceQuery;import org.activiti.engine.repository.Deployment;import org.activiti.engine.repository.ProcessDefinition;import org.activiti.engine.repository.ProcessDefinitionQuery;import org.activiti.engine.runtime.ProcessInstance;import org.activiti.engine.task.Task;import org.activiti.engine.task.TaskQuery;import org.junit.Test;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.test.context.junit4.SpringRunner;@RunWith(SpringRunner.class)@SpringBootTestpublic class SpringBootActApplicationTests {    @Autowired    private ProcessEngine processEngine;    @Autowired    private RepositoryService repositoryService;    @Autowired    private RuntimeService runtimeService;    @Autowired    private TaskService taskService;    @Autowired    private HistoryService historyService;    @Test    public void contextLoads() {        // ProcessEngineImpl        // 1)依赖jar包优先级(将mybatis的依赖关系放置在前面)        // 2) 新版本的activiti框架需要在classpath中增加processes文件夹。        //System.out.println( "processEngine = " + processEngine );        //RepositoryService repositoryService = processEngine.getRepositoryService();        System.out.println(repositoryService);    }    @Test    public void sendMail() {        repositoryService        .createDeployment()        .addClasspathResource("MyProcess8.bpmn")        .deploy();        // 获取流程定义ID    ProcessDefinition pd =      repositoryService        .createProcessDefinitionQuery()        .processDefinitionKey("myProcess")        .latestVersion()        .singleResult();    // 启动    ProcessInstance pi =        runtimeService.startProcessInstanceById(pd.getId());    }    @Test    public void processListener() {        repositoryService        .createDeployment()        .addClasspathResource("MyProcess7.bpmn")        .deploy();    // 获取流程定义ID    ProcessDefinition pd =      repositoryService        .createProcessDefinitionQuery()        .processDefinitionKey("myProcess")        .latestVersion()        .singleResult();    // 启动    ProcessInstance pi =        runtimeService.startProcessInstanceById(pd.getId());        List<Task> tasks = taskService.createTaskQuery().taskAssignee("zhangsan").list();        for ( Task task : tasks ) {            Map<String, Object> varMap = new HashMap<String, Object>();            varMap.put("status", "refuse");            System.out.println("zhangsan完成了任务 =" + task.getName());            taskService.complete(task.getId(), varMap);        }    }    @Test    public void gateway3() {        // 网关其实就是流程中的逻辑分支判断        // 包含(排他+并行)网关:多个逻辑分支不一定全部满足,根据条件执行不同的分支。        //         如果多个分支只有一个条件成立,那么等同于排他网关        //         如果多个分支有多个条件成立,那么等同于并行网关        repositoryService        .createDeployment()        .addClasspathResource("MyProcess6.bpmn")        .deploy();    // 获取流程定义ID    ProcessDefinition pd =      repositoryService        .createProcessDefinitionQuery()        .processDefinitionKey("myProcess")        .latestVersion()        .singleResult();    Map<String, Object> varMap = new HashMap<String, Object>();    varMap.put("days", 5);    varMap.put("cost", 20000);    // 启动    ProcessInstance pi =        runtimeService.startProcessInstanceById(pd.getId(), varMap);    List<Task> tasks = taskService.createTaskQuery().taskAssignee("zhangsan").list();    List<Task> tasks1 = taskService.createTaskQuery().taskAssignee("lisi").list();    System.out.println("zhangsan的任务数量 =" +tasks.size());    System.out.println("lisi的任务数量 =" +tasks1.size());    for ( Task task : tasks ) {        System.out.println("zhangsan完成任务 = " + task.getName());        taskService.complete(task.getId());    }    // 历史查询    HistoricProcessInstanceQuery hpiQuery =        historyService.createHistoricProcessInstanceQuery();    HistoricProcessInstance hpi =        hpiQuery.processInstanceId(pi.getId()).finished().singleResult();    System.out.println("流程【"+pi.getId()+"】是否结束 = " + (hpi != null));    tasks = taskService.createTaskQuery().taskAssignee("zhangsan").list();    tasks1 = taskService.createTaskQuery().taskAssignee("lisi").list();    System.out.println("zhangsan的任务数量 =" +tasks.size());    System.out.println("lisi的任务数量 =" +tasks1.size());    for ( Task task : tasks1 ) {        System.out.println("lisi完成任务 = " + task.getName());        taskService.complete(task.getId());    }    hpiQuery =            historyService.createHistoricProcessInstanceQuery();    hpi =        hpiQuery.processInstanceId(pi.getId()).finished().singleResult();    System.out.println("流程【"+pi.getId()+"】是否结束 = " + (hpi != null));    }    @Test    public void gateway2() {        // 网关其实就是流程中的逻辑分支判断        // 并行网关:多个逻辑分支同时满足,同时执行。        //         如果其中一个分支执行完毕,流程不会继续执行,        //         需要等待其他所有的分支全部执行完毕,流程才会继续执行        // 会签        repositoryService            .createDeployment()            .addClasspathResource("MyProcess5.bpmn")            .deploy();        // 获取流程定义ID        ProcessDefinition pd =          repositoryService            .createProcessDefinitionQuery()            .processDefinitionKey("myProcess")            .latestVersion()            .singleResult();        // 启动        ProcessInstance pi =            runtimeService.startProcessInstanceById(pd.getId());        List<Task> tasks = taskService.createTaskQuery().taskAssignee("zhangsan").list();        List<Task> tasks1 = taskService.createTaskQuery().taskAssignee("lisi").list();        System.out.println("zhangsan的任务数量 =" +tasks.size());        System.out.println("lisi的任务数量 =" +tasks1.size());        for ( Task task : tasks ) {            System.out.println("zhangsan完成任务 = " + task.getName());            taskService.complete(task.getId());        }        // 历史查询        HistoricProcessInstanceQuery hpiQuery =            historyService.createHistoricProcessInstanceQuery();        HistoricProcessInstance hpi =            hpiQuery.processInstanceId(pi.getId()).finished().singleResult();        System.out.println("流程【"+pi.getId()+"】是否结束 = " + (hpi != null));        tasks = taskService.createTaskQuery().taskAssignee("zhangsan").list();        tasks1 = taskService.createTaskQuery().taskAssignee("lisi").list();        System.out.println("zhangsan的任务数量 =" +tasks.size());        System.out.println("lisi的任务数量 =" +tasks1.size());        for ( Task task : tasks1 ) {            System.out.println("lisi完成任务 = " + task.getName());            taskService.complete(task.getId());        }        hpiQuery =                historyService.createHistoricProcessInstanceQuery();        hpi =            hpiQuery.processInstanceId(pi.getId()).finished().singleResult();        System.out.println("流程【"+pi.getId()+"】是否结束 = " + (hpi != null));    }    @Test    public void gateway1() {        // 网关其实就是流程中的逻辑分支判断        // 排他网关:多个逻辑分支,同时只能执行一个。        // 决策        repositoryService            .createDeployment()            .addClasspathResource("MyProcess4.bpmn")            .deploy();        // 获取流程定义ID        ProcessDefinition pd =          repositoryService            .createProcessDefinitionQuery()            .processDefinitionKey("myProcess")            .latestVersion()            .singleResult();        // 声明变量集合        Map<String, Object> varMap = new HashMap<String, Object>();        varMap.put("days", 5);        // 启动        ProcessInstance pi =            runtimeService.startProcessInstanceById(pd.getId(), varMap);        List<Task> tasks = taskService.createTaskQuery().taskAssignee("zhangsan").list();        for ( Task t : tasks ) {            System.out.println("zhangsan完成了任务= " +t.getName());            taskService.complete(t.getId());        }        // 历史查询        HistoricProcessInstanceQuery hpiQuery =            historyService.createHistoricProcessInstanceQuery();        HistoricProcessInstance hpi =            hpiQuery.processInstanceId(pi.getId()).finished().singleResult();        System.out.println("流程【"+pi.getId()+"】是否结束 = " + (hpi != null));    }    @Test    public void procVar() {        // 如果流程中使用了流程变量,必须要在变量使用前进行赋值        repositoryService            .createDeployment()            .addClasspathResource("MyProcess3.bpmn")            .deploy();        // 获取流程定义ID        ProcessDefinition pd =          repositoryService            .createProcessDefinitionQuery()            .processDefinitionKey("myProcess")            .latestVersion()            .singleResult();        // 声明变量集合        Map<String, Object> varMap = new HashMap<String, Object>();        varMap.put("TL", "wangwu");        // 启动        ProcessInstance pi =            runtimeService.startProcessInstanceById(pd.getId(), varMap);        List<Task> tasks = taskService.createTaskQuery().taskAssignee("wangwu").list();        varMap.put("PM", "zhaoliu");        for ( Task t : tasks ) {            // 完成任务时,可以传递流程变量            taskService.complete(t.getId(), varMap);        }    }    @Test    public void allStep() {        // 部署        repositoryService            .createDeployment()            .addClasspathResource("MyProcess2.bpmn")            .deploy();        // 获取流程定义ID        ProcessDefinition pd =          repositoryService            .createProcessDefinitionQuery()            .processDefinitionKey("myProcess")            .latestVersion()            .singleResult();        // 启动        ProcessInstance pi = runtimeService.startProcessInstanceById(pd.getId());        // 完成任务        TaskQuery query = taskService.createTaskQuery();        List<Task> ts = query.taskAssignee("zhangsan").list();        for ( Task t : ts ) {            System.out.println( "zhangsan完成的任务 =" + t.getName() );            taskService.complete(t.getId());        }        // 历史查询        HistoricProcessInstanceQuery hpiQuery =            historyService.createHistoricProcessInstanceQuery();        HistoricProcessInstance hpi =            hpiQuery.processInstanceId(pi.getId()).finished().singleResult();        System.out.println("流程【"+pi.getId()+"】是否结束 = " + (hpi != null));        query = taskService.createTaskQuery();        ts = query.taskAssignee("lisi").list();        for ( Task t : ts ) {            System.out.println( "lisi完成的任务 =" + t.getName() );            taskService.complete(t.getId());        }        hpiQuery =            historyService.createHistoricProcessInstanceQuery();        hpi =            hpiQuery.processInstanceId(pi.getId()).finished().singleResult();        System.out.println("流程【"+pi.getId()+"】是否结束 = " + (hpi != null));    }    @Test    public void loadHistoryData() {        HistoricProcessInstanceQuery query =            historyService.createHistoricProcessInstanceQuery();        HistoricProcessInstance hpi = query.processInstanceId("12501").finished().singleResult();        System.out.println("历史流程实例 =" +hpi);    }    @Test    public void nextStep() {        // 让流程执行后续操作(下一步)        // 获取任务        TaskQuery query = taskService.createTaskQuery();        List<Task> ts = query.list();        for ( Task t : ts ) {            // 完成任务,流程继续执行            System.out.println( "完成任务 = " + t.getName() );            taskService.complete(t.getId());        }    }    @Test    public void startInstance() {        // 创建流程实例(流程定义的具体应用)        String id =            repositoryService                .createProcessDefinitionQuery()                .latestVersion().singleResult().getId();        /*         * 启动流程实例之后,数据库表数据会发生变化         * 当启动后,流程框架会自动执行开始(start)操作,然后跳转到第一个task(任务)         * act_hi_actinst :历史节点表,将流程的每一个执行节点数据保存。         * act_hi_procinst :历史流程实例表, 保存当前流程实例数据         * act_hi_taskinst :历史流程任务表,保存执行的任务信息         * act_ru_execution : 运行时流程执行实例表, 保存当前流程执行实例数据         * act_ru_task : 运行时任务表,保存了当前流程执行时任务数据         */        runtimeService.startProcessInstanceById(id);    }    @Test    public void loadDataFromDB() {        // 获取查询对象,通过对象所提供的方法对数据库进行访问        ProcessDefinitionQuery query =            repositoryService.createProcessDefinitionQuery();        // 查询数据        List<ProcessDefinition> pds = query.list();        for ( ProcessDefinition pd : pds ) {            //System.out.println( "key = " + pd.getKey() + ", name = " + pd.getName() + ", version = " + pd.getVersion());        }        // 根据条件查询        /*        pds = query.processDefinitionVersion(1).list();        for ( ProcessDefinition pd : pds ) {            //System.out.println( "key = " + pd.getKey() + ", name = " + pd.getName() + ", version = " + pd.getVersion());        }        */        // 获取最新版本的数据        /*        ProcessDefinition pd = query.orderByProcessDefinitionVersion().desc().list().get(0);        System.out.println( "version = " + pd.getVersion());        */        /*        ProcessDefinition pd = query.latestVersion().singleResult();        System.out.println( "version = " + pd.getVersion());        */        // 分页查询数据        //query.listPage((pageno-1)*pagesize, pagesize);        //int cnt = (int)query.count();    }    @Test    public void loadImgData() {        // 将流程定义图形加载到流程框架中,让流程可以自动执行        // 部署(流程图==> DB)        // DeploymentEntity(id=1/*         * 部署流程图形时,数据库中会有3张表发生变化         * act_ge_bytearray(2) : 保存当前流程的文件和图形信息         * act_re_deployment(1) : 部署信息表, 保存当前部署信息(主键,时间)         * act_re_procdef(1) : 流程定义表,保存当前流程定义信息(id, name, version)         */        Deployment d = repositoryService            .createDeployment()            .addClasspathResource("MyProcess1.bpmn")            .deploy();        System.out.println("将流程定义图形加载到数据库中 = " + d);    }}