Activiti工作流简单入门 (zhuan)
https://my.oschina.NET/Barudisshu/blog/309721
***********************************************
BPMN 2.0
BPMN最初由业务流程倡议组织(BPMI)定案,现在BPMI并入到OMG(Object Management Group)了,则由OMG建立规范和维护。
BPMN 2.0正式更名为(Business Process Model And Notation)业务流程符号和模型,也有人继续称呼为业务流程建模标记法(Business Process Modeling Notaion),不过无所谓,不管是jBPM、Activiti还是国人开发的FixFlow,都遵循BPMN规范。
Maven配置
JBoss的开源框架都是比较庞大的,不过相对Activiti体积要小一点。下面为配置的依赖项。
<!--Junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<!--activiti-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti.version}</version>
</dependency>
<!--apache组件-->
...
整合数据库
为什么要整合数据库?如果不整合数据库,我们大可以使用Quartz这些框架来做流程任务。实际上,Work Flow是用于一种长周期的、几乎异步的项目运行环境中,并且我们时刻需要将工作流程的状态记录下来,就是一种既注重结果,又注重过程的事务中,因此,整合数据库很有必要。
下面为配置源数据的XML文件,并且将databaseSchemaUpdate属性配置为drop-create,即在运行前删除原有的数据内容。
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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">
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<property name="databaseSchemaUpdate" value="drop-create"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/db_activiti?useUnicode=true&characterEncoding=utf-8"/>
<property name="jdbcDriver" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUsername" value="root"/>
<property name="jdbcPassword" value="****"/>
<property name="jobExecutorActivate" value="true"/>
</bean>
</beans>
默认配置文件名为activiti.cfg.xml,可以在源文件中找到。
另外,如果有必要,请将MySQL设置为区分大小写,即lower_case_table_names = 0。
数据内容会在运行前自动创建,详细表结构内容可参考官网完整信息。
创建工作流文件
由于BPMN规范的作用,一些高级的IDE会自动识别后缀为*.bpmn的文件,不过这些都无所谓,bpmn文件实际上就是XML文件,只是加上了一些图形的标记,如width、height、x和y的坐标,下面为一个招聘面试流程,只包含流程节点,不包含位置标记节点。
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL"
xmlns:activiti="http://activiti.org/bpmn"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
targetNamespace="Examples"
xsi:schemaLocation="http://www.omg.org/spec/BPMN/20100524/MODEL
http://www.omg.org/spec/BPMN/2.0/20100501/BPMN20.xsd">
<process id="Interview" name="某公司2012年实习生招聘流程">
<documentation>招聘工作流程</documentation>
<startEvent id="start" name="实习生招聘启动"/>
<userTask id="bishi" name="笔试" activiti:candidateGroups="人力资源部"/>
<sequenceFlow id="flow1" name="" sourceRef="start" targetRef="bishi"/>
<userTask id="yimian" name="技术一面" activiti:candidateGroups="技术部"/>
<sequenceFlow id="flow2" name="" sourceRef="bishi" targetRef="yimian"/>
<userTask id="ermian" name="技术二面" activiti:candidateGroups="技术部"/>
<sequenceFlow id="flow3" name="" sourceRef="yimian" targetRef="ermian"/>
<userTask id="hrmian" name="HR面" activiti:candidateGroups="人力资源部"/>
<sequenceFlow id="flow4" name="" sourceRef="ermian" targetRef="hrmian"/>
<userTask id="luyong" name="录用,发放Offer" activiti:candidateGroups="人力资源部"/>
<sequenceFlow id="flow5" name="" sourceRef="hrmian" targetRef="luyong"/>
<endEvent id="end" name="实习生招聘结束"/>
<sequenceFlow id="flow6" name="" sourceRef="luyong" targetRef="end"/>
</process>
</definitions>
为了便于阅读,一些高级IDE可以转化为图形符号,如下图:

测试运行
有了流程引擎的配置文件和流程文件后,就可以编写代码启动流程引擎并加载该流程文件了。测试清单如下:
@Test
public void processTests(){
// 加载配置文件
ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml").buildProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
RuntimeService runtimeService = processEngine.getRuntimeService();
repositoryService.createDeployment().addClasspathResource("Interview.bpmn").deploy();
String processId = runtimeService.startProcessInstanceByKey("Interview").getId();
TaskService taskService = processEngine.getTaskService();
//得到笔试的流程
System.out.println("\n***************笔试流程开始***************");
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("人力资源部").list();
for (Task task : tasks) {
System.out.println("人力资源部的任务:name:"+task.getName()+",id:"+task.getId());
taskService.claim(task.getId(), "张三");
}
System.out.println("张三的任务数量:"+taskService.createTaskQuery().taskAssignee("张三").count());
tasks = taskService.createTaskQuery().taskAssignee("张三").list();
for (Task task : tasks) {
System.out.println("张三的任务:name:"+task.getName()+",id:"+task.getId());
taskService.complete(task.getId());
}
System.out.println("张三的任务数量:"+taskService.createTaskQuery().taskAssignee("张三").count());
System.out.println("***************笔试流程结束***************");
System.out.println("\n***************一面流程开始***************");
tasks = taskService.createTaskQuery().taskCandidateGroup("技术部").list();
for (Task task : tasks) {
System.out.println("技术部的任务:name:"+task.getName()+",id:"+task.getId());
taskService.claim(task.getId(), "李四");
}
System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count());
for (Task task : tasks) {
System.out.println("李四的任务:name:"+task.getName()+",id:"+task.getId());
taskService.complete(task.getId());
}
System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count());
System.out.println("***************一面流程结束***************");
System.out.println("\n***************二面流程开始***************");
tasks = taskService.createTaskQuery().taskCandidateGroup("技术部").list();
for (Task task : tasks) {
System.out.println("技术部的任务:name:"+task.getName()+",id:"+task.getId());
taskService.claim(task.getId(), "李四");
}
System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count());
for (Task task : tasks) {
System.out.println("李四的任务:name:"+task.getName()+",id:"+task.getId());
taskService.complete(task.getId());
}
System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count());
System.out.println("***************二面流程结束***************");
System.out.println("***************HR面流程开始***************");
tasks = taskService.createTaskQuery().taskCandidateGroup("人力资源部").list();
for (Task task : tasks) {
System.out.println("技术部的任务:name:"+task.getName()+",id:"+task.getId());
taskService.claim(task.getId(), "李四");
}
System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count());
for (Task task : tasks) {
System.out.println("李四的任务:name:"+task.getName()+",id:"+task.getId());
taskService.complete(task.getId());
}
System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count());
System.out.println("***************HR面流程结束***************");
System.out.println("\n***************录用流程开始***************");
tasks = taskService.createTaskQuery().taskCandidateGroup("人力资源部").list();
for (Task task : tasks) {
System.out.println("技术部的任务:name:"+task.getName()+",id:"+task.getId());
taskService.claim(task.getId(), "李四");
}
System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count());
for (Task task : tasks) {
System.out.println("李四的任务:name:"+task.getName()+",id:"+task.getId());
taskService.complete(task.getId());
}
System.out.println("李四的任务数量:"+taskService.createTaskQuery().taskAssignee("李四").count());
System.out.println("***************录用流程结束***************");
HistoryService historyService = processEngine.getHistoryService();
HistoricProcessInstance historicProcessInstance = historyService
.createHistoricProcessInstanceQuery()
.processInstanceId(processId).singleResult();
System.out.println("\n流程结束时间:"+historicProcessInstance.getEndTime());
}
代码清单中使用 ProcessEngines类加载默认的流程配置文件(activiti.cfg.xml),再获取各个服务组件的实例。 RepositoryService主要用于管理流程的资源, RuntimeService主要用于流程运行时的流程管理,TaskService主要用于管理流程任务。最后, HistoricProcessInstance会将工作的流程历史记录下来。
Activiti工作流简单入门 (zhuan)的更多相关文章
- 【知识总结】Activiti工作流学习入门
1. 我理解的工作流: 在工作中慢慢接触的业务流程,就向流程控制语言一样,一步一步都对应的不同的业务,但整体串联起来就是一个完整的业务.而且实际工作中尤其是在企业内部系统的研发中,确实需要对应许多审批 ...
- springboot activiti工作流简单示例
最近一直研究springboot,根据工作需求,工作流需要作为一个单独的微服务工程来提供给其他服务调用,现在简单的写下工作流(使用的activiti)微服务的搭建与简单使用 jdk:1.8 数据库:m ...
- 使用idea进行activiti工作流开发入门学习
1.安装插件 在idea里面,activiti的插件叫actiBPM,在插件库里面把它安装好,重启idea就行了. 2.新建一个maven项目,并更改pom.xml.pom中依赖如下: <?xm ...
- Activiti工作流的入门介绍
一.activiti介绍 Activiti5是一个 业务流程管理(BPM)框架,它是覆盖了业务流程管理.工作流.服务协作等领域的一个开源的.灵活的.易扩展的可执行流程语言框架.Activiti基于Ap ...
- 一、activiti工作流(workflow)入门介绍
activiti官方网站(官网通常很卡,不建议看,直接看我教程就行) http://www.activiti.org/ eclipse离线安装activiti插件并下载教程 https://downl ...
- Activiti的简单入门样例(经典的请假样例)
经典的请假样例: 流程例如以下,首先须要部门经理审批.假设请假天数大于2天,则须要总经理审批,否则HR审批就可以 一:创建maven项目,项目结构例如以下: watermark/2/text/aHR0 ...
- Activiti工作流小序曲
一般涉及到OA.ERP等公司办公系统都必须有一套办公流程,这时候使用activiti工作流框架会大大减轻我们的工作量,提高我们的开发效率. Activiti工作流简单介绍: 工作流(workflow) ...
- activiti工作流入门学习
工作流一般在OA系统用的比较多,当然,只要有流程审批的地方都会用到,activiti只是开源的工作流中比较流行的一个,还有其他的开源的工作流,这里学习activiti工作流:前面部分是关于activi ...
- 【Activiti工作流引擎】官方快速入门demo
Activiti官方快速入门demo 地址: https://www.activiti.org/quick-start 0. 版本 activiti 5.22.0 JDK 1.8 1. 介绍 这个快速 ...
随机推荐
- 数学图形(2.5)Loxodrome曲线
这也是一种贴在球上的曲线 #http://www.mathcurve.com/courbes3d/loxodromie/sphereloxodromie.shtml vertices = 1000 t ...
- 如何快速把安卓应用移植到BlackBerry 10上
如何快速把安卓应用移植到BlackBerry 10上 相关博客: BlackBerry相关文档 http://developer.blackberry.com/android/documentatio ...
- Ubuntu简单搭建git私有服务
gitserver搭建过程 搭建gitserver过程记录 例如以下: 环境: serverUbuntu虚拟机(Boss),能通过网络訪问到(server地址:192.168.9.103). clie ...
- 性能测试工具 nGrinder 项目剖析及二次开发
转:https://testerhome.com/topics/4225 0.背景 组内需要一款轻量级的性能测试工具,之前考虑过LR(太笨重,单实例,当然它的地位是不容置疑的),阿里云的PTS(htt ...
- JavaScript 正则表达式——基本语法(2)
来源:http://www.cnblogs.com/dolphinX/p/3486214.html 定义 JavaScript种正则表达式有两种定义方式,定义一个匹配类似 <%XXX%> ...
- data目录和binlog目录搬迁的方法
刚开始安装时使用了默认目录,使用一段时间,数据慢慢变在,发现当前设置的目录空间不够时,就要搬迁数据到另一个目录了 如果全过程使用的是Mysql用户,应该可以正常启动. 如果用的ROOT用户,可能不能正 ...
- IIS7.5 取消301重定向
今天想把一个域名解析到对应的www的域名,添加了301重定向. 结果域名解析那里是把www解析到了对应的域名,结果就是重定向循环.立即删除了IIS中重定向,结果还是无法解决. 以为是有缓存,重 ...
- angularjs中ng-repeat的使用
第一个例子:使用ng-repeat最简单的例子 <html ng-app="myApp"> <head> <title>angularjs-de ...
- HDU1004——Let the Balloon Rise
Problem Description Contest time again! How excited it is to see balloons floating around. But to te ...
- CSDN日报20170401 ——《假设你还是“程序猿”,我劝你别创业!》
[程序人生]假设你还是"程序猿".我劝你别创业! 作者:北漂周 在IT这一行做得久了,会接触到无数让人哭笑不得的外行话. 「我们就差一个写代码的了」是当中典型的一种,之所以黑它.不 ...