简单的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); }}
- 简单的activiti5流程框架代码实现:
- Spring整合Activiti5.10完成一个简单的请假流程
- Activiti5流程基本代码,以及相应数据库的变化
- activiti5.20简单介绍(二) -- 流程文件
- activiti5.20简单介绍(七) -- 流程操作
- activiti5.20简单介绍(八) -- 流程操作续
- activiti5.20简单介绍(八) -- 流程操作续
- Activiti5小试牛刀demo流程
- 三、Activiti5 流程管理
- Jbpm4或Activiti5的流程任务分发与汇总
- activiti5.20简单介绍(六) -- 流程引擎和流程服务
- 代码测试的简单框架
- 代码测试的简单框架
- 代码测试的简单框架
- PHP ORM框架与简单代码实现
- symfony框架简单流程
- Activiti5学习笔记(一)简单的预算审批
- Activiti5学习笔记(一)简单的预算审批
- mysql开启慢日志(操作)
- 习题6;6.1.2
- 学习《js高级程序设计》(1)——执行环境及作用域
- Java通过I/O简单记事本(暂时读写功能,等待完善)
- www
- 简单的activiti5流程框架代码实现:
- leetcode: 29. Divide Two Integers [✗]
- ListView两种读取数据库表的方式
- 关键活动(30 分)
- leetcode: 30. Substring with Concatenation of All Words [✗]
- 谷歌大脑自门控激活函数Swish
- Presto学习-presto的安装
- springcloud-服务提供与注册Eureka
- 数学坑