介绍工作流

  网上工作流的定义一大堆,这里就不去复制了,通俗的理解,工作流就是类似OA系统中请假审批、报销审批等一系列流程,下级提交的申请只有直系领导才能审批,其他人是没有权限的,而只有直系领导审批通过后,直系领导的直系领导才可以看到申请,并进行审批,以此类推。。。

  而Activiti工作流就可以实现类似的功能,本笔记将以最简单的方式让你明白怎么使用Activiti工作流,直接上代码

准备环境

1) JDK1.6或者更高版本

2) 支持的数据库有:h2, mysql, oracle, postgres, mssql, db2等。

3) 支持activiti5运行的jar包

4) 开发环境为Eclipse3.7或者以上版本,myeclipse为8.6版本

安装流程设计器(eclipse插件)

方案一:

有网络的情况下,安装流程设计器步骤如下:

1) 打开 Help -> Install New Software. 在如下面板中:

2) 在如下Install界面板中,点击Add按钮:

3) 然后填入下列字段

Name: Activiti BPMN 2.0 designer

Location: http://activiti.org/designer/update/

4) 回到Install界面,在面板正中列表中把所有展示出来的项目都勾上:

5) 点击复选框

在Detail部分记得选中 "Contact all updates sites.." , 因为它会检查所有当前安装所需要的插件并可以被Eclipse下载.

6) 安装完以后,点击新建工程new->Other…打开面板,如果看到下图内容:

说明安装成功了。

方案二

没有网络的情况下,安装流程设计器步骤如下:

首先下载离线插件包:

https://files.cnblogs.com/files/lm970585581/activiti.zip

将压缩包解压后

这两个文件夹复制到Eclipse根目录下 ,重启即可

注意:

打开菜单Windows->Preferences->Activiti->Save下流程流程图片的生成方式:

虽然流程引擎在单独部署bpmn文件时会自动生成图片,但在实际开发过程中,自动生成的图片会导致和BPMN中的坐标有出入,在实际项目中展示流程当前位置图会有问题。

所在完成以上配置后,会由我们自己来管理流程图片。在发布流程时把流程规则文件和流程图片一起上传就行了。

准备Activiti5开发环境

在activiti-5.13->wars目录下是一些示例项目,解压activiti-rest项目,导入activiti-rest目录中WEB-INF\lib下所有包。添加到classpath中。

另外需要根据我们正在使用的数据库添加相应的数据库jar包

初始化数据库

可以在activiti-rest\WEB-INF\classes下找到配置文件:如下

<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
<property name="jdbcUrl" value="jdbc:mysql://192.168.220.130:3306/activiti?useUnicode=true&amp;characterEncoding=utf8"></property>
<property name="jdbcUsername" value="root"></property>
<property name="jdbcPassword" value="root"></property>
<!--
创建表的策略
-->
<property name="databaseSchemaUpdate" value="true"></property>
</bean>
</beans>

调用以下java代码,即可把需要的表创建出来

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.junit.Test; public class CreateTable {
@Test
public void testCreateTable(){
ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml")
.buildProcessEngine();
}
}

HelloWorld程序

先画请假流程图

注意:

properties=>General中的ID和NAME可以设置每个步骤的名称:

每个审批过程的properties=>Main config=>Assignee:设置能够审批的对象,这里部门经理审批设置为:张三,总经理审批设置为:李四

保存后,在根目录下生成:

JAVA程序如下:

import java.util.List;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.task.Task;
import org.junit.Test; /**
* 1、部署流程图
* 2、启动流程实例
* 3、发起申请
* 4、审批
* @author zd
*
*/
public class HelloWorld {
/**
* 部署流程图
*/
@Test
public void testDeploy(){
//产生流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取仓库流程的实例
processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("qingjia.bpmn")
.addClasspathResource("qingjia.png")
.deploy();
/**
* 这里使用RepositoryService部署流程定义
addClasspathResource表示从类路径下加载资源文件,一次只能加载一个文件
*/
} /**
* 启动流程实例 pi=process instance
*/
@Test
public void testStartPI(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRuntimeService()
.startProcessInstanceById("qingjia:1:4");//ID在act_re_procdef这个表中可以看到
//这里使用RuntimeService启动流程实例
} /**
* 完成任务
*/
@Test
public void testFinishTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete("104");//act_ru_task表中获取
} /**
* 根据张三查询任务
*/
@Test
public void testQueryTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//查询任务列表
List<Task> tasks = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee("张三")
.list();
for (Task task : tasks) {
System.out.println(task.getName());
}
}
}

流程定义

import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.zip.ZipInputStream; import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.junit.Test;
import org.springframework.transaction.annotation.Transactional; /**
* pd=process definition
* @author zd
* 1、把流程图部署到activiti的引擎中 重点
* classpath
* inputstream
* zipinputstream
* 2、对流程图进行删除 重点
* 3、获取到流程图和bpmn文件 重点
* 4、查询 了解
* 查询部署
* 查询流程定义
*/
public class PDTest {
/**
* 涉及到的表
* act_ge_bytearray
* 1、说明
* 该表存储了bpmn文件和png图片
* 从字段可以看出,根据deploymentID可以查询bpmn文件和png图片
* 2、字段
* name_:存储该文件的路径名称
* deploymentid_id_:部署表的ID
* byte_:存放值(bpmn和png)
* act_re_deployment
* 1、说明
* 该表存储了部署的动作
* 2、字段
* ID_:部署ID 主键
* act_re_procdef
* 1、说明
* 流程定义表
* 2、字段
* id: 是由${name}:${version}:随机数 确定唯一的流程
* name_: 流程定义名称
* key_: 流程定义名称
* version_: 某一个流程定义的版本
* deployment_id_:部署表的ID
*
* 说明:
* 1、根据deploymentID-->查询图片和bpmn文件
* 2、根据deploymentID-->查询流程定义
* 3、只要流程名称不变,部署一次,版本号加1,id就发生变化,生成了一个新的deploymentID
* 4、所以deploymentID和pdid是一一对应的关系
*/
@Test
public void testDeployFromClasspath(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addClasspathResource("qingjia.bpmn")
.addClasspathResource("qingjia.png")
.deploy();
} /**
* 通过inputStream的方式部署
*/
@Test
public void testDeployFromInputStream(){
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("qingjia.bpmn");
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addInputStream("qingjia.bpmn", inputStream)
.deploy();
} /**
* 通过zip的方式部署
*/
@Test
public void testDeployFromZip(){
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("qingjia.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
} /**
* 把查询出来的图片放到E盘的根目录下
*/
@Test
public void testShowImage() throws Exception{
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
InputStream inputStream = processEngine.getRepositoryService()
/**
* 参数为pdid
*/
.getProcessDiagram("qingjia:1:4");
/**
* 得到一个图片
*/
// OutputStream outputStream = new FileOutputStream("e:/processimg.png");
// for(int b=-1;(b=inputStream.read())!=-1;){
// outputStream.write(b);
// }
// inputStream.close();
// outputStream.close();
/***************************************************************************************/
/**
* 第一个参数为deploymentId
* 第二个参数为resourceName
*/
/********************************************************************************/
/**
* 得到的是一个图片
*/
// InputStream inputStream2 = processEngine.getRepositoryService()
// .getResourceAsStream("101", "qingjia.png");
//
// OutputStream outputStream2 = new FileOutputStream("e:/processimg2.png");
// for(int b=-1;(b=inputStream2.read())!=-1;){
// outputStream2.write(b);
// }
// inputStream2.close();
// outputStream2.close();
/**********************************************************************************/
/**
* 得到的是bpmn文件
*/
InputStream inputStream3 = processEngine.getRepositoryService()
.getProcessModel("qingjia:1:4");
OutputStream outputStream3 = new FileOutputStream("e:/processimg3.bpmn");
for(int b=-1;(b=inputStream3.read())!=-1;){
outputStream3.write(b);
}
inputStream3.close();
outputStream3.close();
/*************************************************************************************/ } /**
* 查询流程部署
*/
@Test
public void testQueryDeploy(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Deployment> deployments = processEngine.getRepositoryService()
.createDeploymentQuery()
.list();
for (Deployment deployment : deployments) {
System.out.println(deployment.getId());
}
} /**
* 根据部署ID查询部署 一个结果
*/
@Test
public void testQueryDeployById(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
Deployment deployment = processEngine.getRepositoryService()
.createDeploymentQuery()
.deploymentId("1")
.singleResult(); System.out.println(deployment.getId()); } /**
* 查询所有的流程定义
*/
@Test
public void testQueryPD(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessDefinition> processDefinitions = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.list();
for (ProcessDefinition processDefinition : processDefinitions) {
System.out.println(processDefinition.getKey());
System.out.println(processDefinition.getId());
System.out.println(processDefinition.getVersion());
}
} /**
* 按照版本的从高到低进行排序
*/
@Test
public void testQueryPDByVersion(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessDefinition> processDefinitions = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.orderByProcessDefinitionVersion()
.desc()
.list();
for (ProcessDefinition processDefinition : processDefinitions) {
System.out.println(processDefinition.getKey());
System.out.println(processDefinition.getId());
System.out.println(processDefinition.getVersion());
}
} /**
* 根据pdid查询流程定义
* 根据 pdkey查询流程定义
*/
//略。。 /**
* 删除
*/
@Test
public void testDelete(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getRepositoryService()
//.deleteDeployment("");//该方法只能删除流程定义,一般不会使用
.deleteDeployment("1", true);//该方法不仅能够删除流程定义,而且能够删除正在运行的流程实例
}
}

流程实例、任务的执行

import java.util.List;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.history.HistoricActivityInstance;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.impl.bpmn.parser.handler.ProcessParseHandler;
import org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntity;
import org.activiti.engine.impl.pvm.process.ActivityImpl;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test; /**
* pi=process instance
* @author zd
* 1、启动流程实例
* 2、完成任务
* 3、任务的查询
* 1、根据任务的执行人查询任务
* 2、可以根据任务查询任务的执行人
* 3、查看历史任务
* 4、怎么样查看流程实例是否结束
*/
public class PITest {
/**
* 启动流程实例
* 涉及到的表
* act_hi_actinst hi:history actinst:action instance
* 1、概念
* 所有的正在执行的或者已经完成的节点
* 2、字段
* act_type_:为节点的类型
* end_time_: 如果有值,说明该节点已经结束了
* act_hi_procinst procinst:process instance
* 1、概念
* 所有的正在执行的或者已经完成的流程实例
* 2、字段
* end_time_:如果该字段有值,说明这个流程实例已经结束了
* end_act_id_:说明该流程实例是在哪个节点结束的
* act_hi_taskinst taskinst:task instance
* 1、概念
* 所有的正在执行的或者已经完成的任务节点
* 2、字段
* end_time_:如果该字段有值,说明任务已经完成了
* delete_reason:如果该值为completed,说明该任务处于完成的状态
* act_ru_execution ru:runtime
* 1、概念
* 代表正在执行的流程实例
* 2、字段
* id_:主键 executionid
* proc_inst_id_: process instanceid
* proc_def_id_:pdid
* act_id_:当前的流程实例正在执行的节点的ID的值
* act_ru_task
* 1、概念
* 代表正在执行的任务
* 2、字段
* id_:主键 任务ID
* execution_id_:piid,executionid
* name_:任务名称
* 3、说明
* 该表是一个临时表,该表中的任务完成以后,这一行会被删除掉
*
*/
@Test
public void testStartPI(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
ProcessInstance pi = processEngine.getRuntimeService()
.startProcessInstanceById("qingjia:1:304");
System.out.println(pi.getId());
} /**
* 查询所有的正在执行的流程实例
*/
@Test
public void testQueryPI(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<ProcessInstance> processInstances = processEngine.getRuntimeService()
.createProcessInstanceQuery()
.list();
for (ProcessInstance processInstance : processInstances) {
System.out.println(processInstance.getActivityId());
System.out.println(processInstance.getId());
}
} /**
* 查询当前正在执行的节点
*/
@Test
public void testQueryActivity(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<String> strings = processEngine.getRuntimeService()
.getActiveActivityIds("401");
for (String string : strings) {
System.out.println(string);
}
} /**
*获取当前的流程实例正在运行的节点的坐标
*/
@Test
public void getPix(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**
* processDefinitionEntity代表流程图对象的实体
*
* 根据pdid获取到流程定义实体
*/
ProcessDefinitionEntity processDefinitionEntity = (ProcessDefinitionEntity)processEngine.getRepositoryService()
.getProcessDefinition("qingjia:1:304");
List<String> strings = processEngine.getRuntimeService()
.getActiveActivityIds("401"); //piid
for (String string : strings) {
/**
* ActivityImpl代表流程图上的每一个节点
*/
ActivityImpl activityImpl = processDefinitionEntity.findActivity(string);
/**
* 获取到正在执行的流程节点的坐标
*/
System.out.println(activityImpl.getHeight());
System.out.println(activityImpl.getWidth());
System.out.println(activityImpl.getX());
System.out.println(activityImpl.getY());
}
} /**
* 查询所有的任务
*/
@Test
public void testQueryAllTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Task> tasks = processEngine.getTaskService()
.createTaskQuery()
.list();
for (Task task : tasks) {
System.out.println(task.getId());
System.out.println(task.getName());
}
} /**
* 完成任务
* 需要一个参数:taskId
*/
@Test
public void testFinishTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
processEngine.getTaskService()
.complete("602");
} /**
* 根据任务的执行人查看任务
*/
@Test
public void testQueryTaskByAssignee(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Task> tasks = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee("张三")
.list();
for (Task task : tasks) {
System.out.println(task.getId());
System.out.println(task.getName());
}
} /**
* 根据任务的执行人查看任务,并且按照时间的倒叙排序
*/
@Test
public void testQueryTaskByAssigneeByTime_DESC(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<Task> tasks = processEngine.getTaskService()
.createTaskQuery()
.taskAssignee("张三")
.orderByTaskCreateTime()
.desc()
.list();
for (Task task : tasks) {
System.out.println(task.getId());
System.out.println(task.getName());
}
} /**
* 根据piid判断流程实例是否结束
*/
@Test
public void testQueryPIByPIID(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
ProcessInstance pi = processEngine.getRuntimeService()
.createProcessInstanceQuery()
.processInstanceId("401")
.singleResult();
if(pi==null){
System.out.println("该流程实例已经结束了");
}else{
System.out.println("该流程实例正在执行中");
}
} /**
* 查询已经完成的任务
*/
@Test
public void testQueryHistoryTask(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<HistoricTaskInstance> historicTaskInstances = processEngine.getHistoryService()
.createHistoricTaskInstanceQuery()
.finished()
.list();
for (HistoricTaskInstance historicTaskInstance : historicTaskInstances) {
System.out.println(historicTaskInstance.getAssignee());
System.out.println(historicTaskInstance.getName());
System.out.println(historicTaskInstance.getId());
}
} /**
* 查询已经完成的activityimpl
*/
@Test
public void testQueryHistoryActivityImpl(){
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
List<HistoricActivityInstance> historicActivityInstances = processEngine.getHistoryService()
.createHistoricActivityInstanceQuery()
.list();
for (HistoricActivityInstance historicActivityInstance : historicActivityInstances) {
System.out.println(historicActivityInstance.getActivityName());
}
}
}

Activiti5工作流笔记二

Activiti5工作流笔记一的更多相关文章

  1. Activiti5工作流笔记四

    排他网关(ExclusiveGateWay) 流程图 部署流程定义+启动流程实例 查询我的个人任务 完成我的个人任务 并行网关(parallelGateWay) 流程图 部署流程定义+启动流程实例 查 ...

  2. Activiti5工作流笔记三

    组任务 直接指定办理人 流程图如下: import java.util.HashMap; import java.util.List; import java.util.Map; import org ...

  3. Activiti5工作流笔记二

    流程变量 import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import org.activiti ...

  4. Java_Activiti5_菜鸟也来学Activiti5工作流_之初识常用服务类和数据表(二)

    /** * 代码清单中使用 ProcessEngines类加载默认的流程配置文件(activiti.cfg.xml),再获取各个服务组件的实例. * RepositoryService主要用于管理流程 ...

  5. activiti工作流笔记

    什么是activiti? Activiti是一个身经百战的业务流程管理引擎, 并且还是一个流程平台 为什么要用工作流引擎? 简单来说,就是为了统一管理流程业务. 想想看,如果要设计一个流程的程序,通常 ...

  6. Activiti工作流笔记(4)

    Activiti工作流启动流程 /** * 启动流程 * */ public class ActivitiTest2 { RepositoryService repositoryService; Ru ...

  7. Activiti工作流笔记(3)

    Activiti工作流的流程部署和删除流程部署 流程部署代码: /** * 部署流程 */ public class ActivitiTest { RepositoryService reposito ...

  8. Activiti工作流笔记(2)

    1.Activiti工作数据表 Activiti用来存放流程数据的表共使用23张表,表名都是以"ACT_"开头,底层操作默认使用mybatis操作 工作流Activiti的表是用来 ...

  9. Activiti工作流笔记(1)

    Activiti下载地址: eclipse的activiti插件下载地址:http://www.activiti.org/designer/archived/activiti-designer-5.1 ...

随机推荐

  1. python 的 购物小程序

    money = input('请输入您的工资:') shop = [("iphone",5800),("ipod",3000),("book" ...

  2. Git使用规范(三)

    今天我们来介绍一下Git的一些操作,这个里面主要是一些我们平时遇到的一些问题 1.当我进入了一个分支的是时候,我在查看git log的时候,为什么会有别人的信息,我一直以为 这个是查看分支提交情况, ...

  3. 转:asp.net mvc ef 性能监控调试工具 MiniProfiler

    MiniProfiler官网:http://miniprofiler.com/ MiniProfiler的一个特别有用的功能是它与数据库框架的集成.除了.NET原生的 DbConnection类,Mi ...

  4. 【独家】K8S漏洞报告 | 近期bug fix解读&1.9.11主要bug fix汇总

    *内容提要: 1. Kube-proxy长连接优雅断开机制及IPVS模式实现 2. 10/29--11/19 bug fix汇总分析 3. 1.9.11重要bug fix汇总 在本周的跟踪分析中,以1 ...

  5. 了解Python控制流语句——if语句

    控制流 截止到现在,在我们所看过的程序中,总是有一系列语句从上到下精确排列,并交由 Python 忠实地执行.如果你想改变这一工作流程,应该怎么做?就像这样的情况:你需要程序作出一些决定,并依据不同的 ...

  6. leetcode-分割回文子串

    给定一个字符串 s,将 s 分割成一些子串,使每个子串都是回文串. 返回 s 所有可能的分割方案. 示例: 输入: "aab" 输出: [ ["aa",&quo ...

  7. spark集群安装部署

    通过Ambari(HDP)或者Cloudera Management (CDH)等集群管理服务安装和部署在此不多介绍,只需要在界面直接操作和配置即可,本文主要通过原生安装,熟悉安装配置流程. 1.选取 ...

  8. C语言链接数据库

    一.解释一下函数功能和用法 1.mysql_real_connect 函数原型:MYSQL *mysql_real_connect(MYSQL *mysql, const char *host, co ...

  9. leetcode个人题解——two sum

    这是leetcode第一题,通过较为简单. 第一题用来测试的,用的c,直接暴力法过, /** * Note: The returned array must be malloced, assume c ...

  10. lvs+keepalived详解

    常用软件安装及使用目录 资源链接:https://pan.baidu.com/s/15rFjO-EnTOyiTM7YRkbxuA    网盘分享的文件在此 官网:http://www.linuxvir ...