一、Activiti简介

  Activiti 是一个针对商务人士、 开发人员和系统管理员的轻量级的工作流和业务流程管理 (BPM) 平台。它的核心是Java的高速和可靠的 BPMN 2 流程引擎。它是开源的、并且提供宽松的Apache许可。Activiti可以在任何Java应用中运行,可以运行在在服务器、集群或云环境。它可以与Spring进行整合,它非常轻便和机遇简单的概念。Activiti是由原来开发JBPM的作者所建立的,所以Activiti与JBPM早期的版本(JBPM4,BPM4之后版本已完全抛弃JBPM4的基础代码,转而基于Drools Flow构建)比较相似,适合于早期的JBPM用户使用。

   Activiti 下载地址为:http://activiti.org/download.html。这里使用的是activiti-5.18.0.zip 版本。

二、eclipse 流程设计器

  使用Activiti需要设计流程,然后再进行部署,运行、流转。这里使用Activiti提供的eclipse插件进行流程设计。以下为插件的安装:

  1、点击eclipse Help -》 Install New Software. 并在界面点击Add输入如下内容,并点击OK按钮。如下图所示

  

  2、点击Select All并点击Next,按照界面的提示直到出现如下界面

  

  点击Finish,等待安装,安装完成重启eclipse即可。

三、Activiti 数据库配置

  activiti-5.17.0.zip下载完成后,解压。将libs下的activiti-engine-5.17.0.jar文件解压。创建数据的脚步就在org\activiti\db\create目录下。 该目录下有多种版本的数据库脚本。

  • engine:为引擎运行所必须的表。
  • identity: 为包含用户,用户组和用户组里的成员。这些表是可选的,但是当引擎是使用默认的身份标识管理进行装载的时候,这些表必须存在。
  • history:这些表包含一些历史和审计信息。当history level 设置成none的时候是可选的,但是这样会使一些存储在history数据库里面的新特性失效(如任务里面的说明)。

  注意:对于mysql来说,版本低于 5.6.4的mysql不支持 带有毫秒精确度的timestamp和date 类型。所以低于 5.6.4版本的mysql需要执行如下脚本文件:

activiti.mysql55.create.engine.sql
activiti.mysql.create.identity.sql
activiti.mysql55.create.history.sql

  而版本号在5.6.4以及以上的mysql需要执行如下脚本

activiti.mysql.create.engine.sql
activiti.mysql.create.identity.sql
activiti.mysql.create.history.sql

  创建完成后,生成的表入下图所示:

  

四、示例

  1、设计流程定义

    选择新建一个Activiti Diagram 命名为test,在拖动Palette中的组件到右边的设计区域。本例子使用到的有StartEvent、UserTask、EndEvent并使用SequenceFlow将它们连接起来,如下图所示:

      

  流程定义文件test.bpmn内容如下图所示:

 <?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.activiti.org/test">
<process id="test" name="My process" isExecutable="true">
<startEvent id="start" name="Start"></startEvent>
<endEvent id="end" name="End"></endEvent>
<userTask id="usertask1" name="step1" activiti:assignee="kermit"></userTask>
<userTask id="usertask2" name="step2" activiti:candidateUsers="kermit,gonzo"></userTask>
<userTask id="usertask3" name="step3" activiti:candidateGroups="management,accountancy"></userTask>
<sequenceFlow id="flow1" sourceRef="start" targetRef="usertask1"></sequenceFlow>
<sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow>
<sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow>
<sequenceFlow id="flow4" sourceRef="usertask3" targetRef="end"></sequenceFlow>
</process>
<bpmndi:BPMNDiagram id="BPMNDiagram_test">
<bpmndi:BPMNPlane bpmnElement="test" id="BPMNPlane_test">
<bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start">
<omgdc:Bounds height="35.0" width="35.0" x="20.0" y="129.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end">
<omgdc:Bounds height="35.0" width="35.0" x="610.0" y="129.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1">
<omgdc:Bounds height="55.0" width="105.0" x="110.0" y="119.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2">
<omgdc:Bounds height="55.0" width="105.0" x="290.0" y="119.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3">
<omgdc:Bounds height="55.0" width="105.0" x="450.0" y="119.0"></omgdc:Bounds>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1">
<omgdi:waypoint x="55.0" y="146.0"></omgdi:waypoint>
<omgdi:waypoint x="110.0" y="146.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2">
<omgdi:waypoint x="215.0" y="146.0"></omgdi:waypoint>
<omgdi:waypoint x="290.0" y="146.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3">
<omgdi:waypoint x="395.0" y="146.0"></omgdi:waypoint>
<omgdi:waypoint x="450.0" y="146.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4">
<omgdi:waypoint x="555.0" y="146.0"></omgdi:waypoint>
<omgdi:waypoint x="610.0" y="146.0"></omgdi:waypoint>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>

  2、代码示例

  工程使用maven构建,pom.xml文件内容如下:

 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion> <groupId>com.shh</groupId>
<artifactId>activitytest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>activitytest</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<activiti-version>5.18.0</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>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-all</artifactId>
<version>2.0.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.35</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jdk14</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>3.2.2.RELEASE</version>
</dependency> <dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>3.2.2.RELEASE</version>
</dependency>
</dependencies>
</project>

  spring配置文件activiti.cfg.xml内容如下:

 <?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="true" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=utf8" />
<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
<property name="jdbcUsername" value="root" />
<property name="jdbcPassword" value="" />
<property name="jobExecutorActivate" value="true" />
</bean>
</beans>

  测试类TestActiviti代码如下:

 package com.shh.test;

 import java.util.List;

 import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.task.Task;
import org.junit.Before;
import org.junit.Test; /**
* 测试流程
* @author 20150205
*
*/
public class TestActiviti {
ProcessEngine processEngine = null;
RepositoryService repositoryService = null;
RuntimeService runtimeService = null;
TaskService taskService = null; @Before
public void init() {
//加载spring配置文件,创建 ProcessEngine
processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml")
.buildProcessEngine();
repositoryService = processEngine.getRepositoryService();
runtimeService = processEngine.getRuntimeService();
taskService = processEngine.getTaskService();
} /**
* 部署流程定义加载test.bpmn文件
*/
@Test
public void deploy(){
Deployment deployment = repositoryService.createDeployment().addClasspathResource("diagrams/test.bpmn").deploy();
String id = deployment.getId();
System.out.println("***************部署流程定义完成***************" + id);
} /**
* 启动一个请假流程
*/
@Test
public void start() {
for(int i = 0 ; i < 5; i++){
String processId = runtimeService.startProcessInstanceByKey("test").getId();
System.out.println("***************启动第" + i + "个请假流程完成***************" + processId);
}
} /**
* 第一步
*/
@Test
public void step1(){
System.out.println("***************step1流程开始***************");
List<Task> tasks = taskService.createTaskQuery().taskAssignee("kermit").list();//kermit的任务
List<Task> tasks2 = taskService.createTaskQuery().taskAssignee("gonzo").list();//gonzo的任务
System.out.println(tasks.size());
System.out.println(tasks2.size());//指定了kermit,所以gonzo的任务数量为0 for (Task task : tasks) {
System.out.println("kermit的任务taskname:" + task.getName() + ",id:" + task.getId());//任务的name与id
System.out.println(task.getAssignee());//任务拥有者
System.out.println(task.getProcessInstanceId());//流程实例id
System.out.println(task.getProcessDefinitionId());//流程定义id
taskService.complete(task.getId());//完成任务
} System.out.println("kermit的任务数量:" + taskService.createTaskQuery().taskAssignee("kermit").count());
System.out.println("***************step1流程结束***************");
} /**
* 第二步
*/
@Test
public void step2(){
System.out.println("***************step2流程开始***************");
List<Task> tasks = taskService.createTaskQuery().taskCandidateUser("kermit").list();//kermit可领取的任务
List<Task> tasks2 = taskService.createTaskQuery().taskCandidateUser("gonzo").list();//gonzo可领取的任务
System.out.println(tasks.size());
System.out.println(tasks2.size()); for (int i = 0 ; i < tasks.size(); i++) {
Task task = tasks.get(i);
System.out.println("任务taskname:" + task.getName() + ",id:" + task.getId());//任务的name与id
if(i % 2 == 0){
taskService.claim(task.getId(), "kermit");//kermit领取任务
}else{
taskService.claim(task.getId(), "gonzo");//gonzo领取任务
}
} tasks = taskService.createTaskQuery().taskAssignee("kermit").list();
tasks2 = taskService.createTaskQuery().taskAssignee("gonzo").list();
System.out.println("kermit的任务数量:" + tasks.size());
System.out.println("gonzo的任务数量:" + tasks2.size()); for(Task t : tasks){
taskService.complete(t.getId());//完成任务
}
for(Task t : tasks2){
taskService.complete(t.getId());//完成任务
}
tasks = taskService.createTaskQuery().taskAssignee("kermit").list();
tasks2 = taskService.createTaskQuery().taskAssignee("gonzo").list();
System.out.println("kermit的任务数量:" + tasks.size());
System.out.println("gonzo的任务数量:" + tasks2.size());
System.out.println("***************step2流程结束***************");
} @Test
public void step3(){
System.out.println("***************step3流程开始***************");
List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();//management组可领取的任务
List<Task> tasks2 = taskService.createTaskQuery().taskCandidateGroup("accountancy").list();//accountancy组可领取的任务
System.out.println(tasks.size());
System.out.println(tasks2.size()); for (int i = 0 ; i < tasks.size(); i++) {
Task task = tasks.get(i);
System.out.println("任务taskname:" + task.getName() + ",id:" + task.getId());//任务的name与id
if(i % 2 == 0){
taskService.claim(task.getId(), "kermit");
}else{
taskService.claim(task.getId(), "gonzo");
}
}
tasks = taskService.createTaskQuery().taskAssignee("kermit").list();
tasks2 = taskService.createTaskQuery().taskAssignee("gonzo").list();
System.out.println("kermit的任务数量:" + tasks.size());
System.out.println("gonzo的任务数量:" + tasks2.size()); for(Task t : tasks){
taskService.complete(t.getId());//完成任务
}
for(Task t : tasks2){
taskService.complete(t.getId());//完成任务
}
tasks = taskService.createTaskQuery().taskAssignee("kermit").list();
tasks2 = taskService.createTaskQuery().taskAssignee("gonzo").list();
System.out.println("kermit的任务数量:" + tasks.size());
System.out.println("gonzo的任务数量:" + tasks2.size()); System.out.println("***************step3流程结束***************");
}
}

  依次执行deploy();、start();、step1();、step2();、step3()方法,结果如下:

八月 04, 2015 10:48:41 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [activiti.cfg.xml]
八月 04, 2015 10:48:44 上午 org.activiti.engine.impl.ProcessEngineImpl <init>
信息: ProcessEngine default created
八月 04, 2015 10:48:44 上午 org.activiti.engine.impl.bpmn.deployer.BpmnDeployer deploy
信息: Processing resource diagrams/test.bpmn
***************部署流程定义完成***************60001
***************启动第0个请假流程完成***************60005
***************启动第1个请假流程完成***************60010
***************启动第2个请假流程完成***************60015
***************启动第3个请假流程完成***************60020
***************启动第4个请假流程完成***************60025
***************step1流程开始***************
5
0
kermit的任务taskname:step1,id:60008
kermit
60005
test:5:60004
kermit的任务taskname:step1,id:60013
kermit
60010
test:5:60004
kermit的任务taskname:step1,id:60018
kermit
60015
test:5:60004
kermit的任务taskname:step1,id:60023
kermit
60020
test:5:60004
kermit的任务taskname:step1,id:60028
kermit
60025
test:5:60004
kermit的任务数量:0
***************step1流程结束***************
***************step2流程开始***************
5
5
任务taskname:step2,id:60031
任务taskname:step2,id:60036
任务taskname:step2,id:60041
任务taskname:step2,id:60046
任务taskname:step2,id:60051
kermit的任务数量:3
gonzo的任务数量:2
kermit的任务数量:0
gonzo的任务数量:0
***************step2流程结束***************
***************step3流程开始***************
5
5
任务taskname:step3,id:60056
任务taskname:step3,id:60060
任务taskname:step3,id:60064
任务taskname:step3,id:60068
任务taskname:step3,id:60072
kermit的任务数量:3
gonzo的任务数量:2
kermit的任务数量:0
gonzo的任务数量:0
***************step3流程结束***************

  

  

activiti入门的更多相关文章

  1. Activiti入门 -- 环境搭建和核心API简介

    相关文章: <史上最权威的Activiti框架学习指南> <Activiti入门 -- 轻松解读数据库> 本章内容,主要讲解Activiti框架环境的搭建,能够使用Activi ...

  2. Activiti入门 -- 轻松解读数据库

    相关文章: <史上最权威的Activiti框架学习指南> <Activiti入门 --环境搭建和核心API简介> 在Activiti中,相对前身JBPM基础上又额外多了5张,框 ...

  3. activiti入门2流程引擎的API和服务基础

      RepositoryService : 管理和控制发布包和流程定义(包含了一个流程每个环节的结构和行为)的操作 除此之外,服务可以 查询引擎中的发布包和流程定义. 暂停或激活发布包,对应全部和特定 ...

  4. activiti入门3排他网关,并行网管,包含网关,事件网关(转)

    网关用来控制流程的流向 网关可以消费也可以生成token. 网关显示成菱形图形,内部有有一个小图标. 图标表示网关的类型. 基本分支 首先 利用 流程变量  写个带有分支的一个基本流程 流程图: 部署 ...

  5. activiti入门2流程引擎API和服务基础设施

    RepositoryService : 管理和控制公布包和流程定义(包括了一个流程每一个环节的结构和行为)的操作 除此之外,服务能够 查询引擎中的公布包和流程定义. 暂停或激活公布包.相应所有和特定流 ...

  6. 工作流引擎activiti入门

    眼下最新的版本号是5.17 1.下载:activiti-5.17.0.zip http://activiti.org/download.html 2.解压activiti-5.17.0.zip 3.打 ...

  7. activiti入门3排他网关,并行网管,包括网关,事件网关

    网关用来控制流程的流向 网关能够消费也能够生成token. 网关显示成菱形图形,内部有有一个小图标. 图标表示网关的类型. 基本分支 首先 利用 流程变量  写个带有分支的一个基本流程 流程图: wa ...

  8. 【Activiti学习之一】Activiti入门

    环境 JDK1.7 MySQL5.6 Tomcat7 Eclipse-Luna activiti 6.0 一.概念1.工作流(Workflow):是一系列相互衔接.自动进行的业务活动或任务.采用工作流 ...

  9. Activiti入门案例

    一.流程定义 Activiti-Designer 使用 Palette(画板) 在eclipse 或 idea 中安装activiti-designer 插件即可使用,画板中包括以下结点: Conne ...

随机推荐

  1. C++学习笔记13:运算符重载(赋值操作符2)

    移动语义 完成所有权的移交,当拷贝构造和赋值构造时,目标对象的所有权必须移交给我们的新的对象,原始对象将丧失所有权,_p指针将不再指向原来的那个数组: 左值与右值 C原始定义 左值:可以出现在赋值号的 ...

  2. Scalaz(24)- 泛函数据结构: Tree-数据游览及维护

    上节我们讨论了Zipper-串形不可变集合(immutable sequential collection)游标,在串形集合中左右游走及元素维护操作.这篇我们谈谈Tree.在电子商务应用中对于xml, ...

  3. log4j配置文件详解

    在开发中经常会碰到日志,网上关于日志的框架也很多,像log4j.self4j.common-logging等,下面对log4j进行介绍. log4j是java开发的日志框架,具有低侵入的特点,其重点使 ...

  4. ahjesus配置vsftpd虚拟用户在Ubuntu

    网上搜索了很多资料,过时,不全,货不对版 已下步骤亲测有效,不包含匿名用户登录 1.新建/home/loguser.txt 并填充内容,格式如下 用户名密码用户名密码用户名密码 2.生成db文件用于用 ...

  5. jquery 集合操作

    修剪字符串 $.trim(value) 功能: 删除传入的字符串开头和结尾的空白 [空白]匹配js正则中的\s,也就是包括空白,换行,回车,制表符,换页以及Unicode字符\u00A0 返回值: 返 ...

  6. php函数的传值如果需要引用传递注意的细节

    Strict standards: Only variables should be passed by reference 网上查到资料有这么一句话: 在php5.3以上版本会出这个问题,应该也和p ...

  7. css选择器中:first-child与:first-of-type的区别

    :first-child选择器是css2中定义的选择器,从字面意思上来看也很好理解,就是第一个子元素.比如有段代码: p:first-child  匹配到的是p元素,因为p元素是div的第一个子元素: ...

  8. eclipse提示:This tag and its children can be replaced by one <TextView/> and a compound drawable

    今天在学习android开发的时候,写了这样的一段代码: <?xml version="1.0" encoding="utf-8"?> <Li ...

  9. php 过滤英文标点符号 过滤中文标点符号

    php 过滤英文标点符号 过滤中文标点符号 代码 function filter_mark($text){ if(trim($text)=='')return ''; $text=preg_repla ...

  10. MSCRM 2013/2015 Ribbon Editor

    由于新版本2015的解决方案与之前有变化,因此许多老的Tools已经不能使用,推荐给大家新的Ribbon Editor Tool. 下载地址: http://www.develop1.net/publ ...