一、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. webservice入门(2)开发ws程序

    因为webservice分为服务端和客户端,所以如果要学习的话,那么肯定是包括这两部分的了. 1.开发服务端的webservice: 使用jdk开发ws其实很简单,只是需要一些注解:最重要的是 @We ...

  2. Elasticsearch5.0.1索引压测结果

    说明 以下的所有指标均指的是某台机器的峰值 机器配置 cpu:12 core,32G,ES 分配JVM内存18G3台虚拟机,master.data共用shard:5,replica:1 试验时间:20 ...

  3. Windows 安装启动apache时出现错误的解决方法

    配置安装Apache主服务发生错误:(OS 5)拒绝访问.  : AH00369: Failed to open the Windows service manager, perhaps you fo ...

  4. Method Draw – 很好用的 SVG 在线编辑器

    Method Draw 是一款在线 SVG 编辑器,是 SVG Edit 的一个分支.Method Draw 的目的是改进 SVG Edit 的可用性和用户体验.它移除了 line-caps/corn ...

  5. JS高程2.在HTML中使用Javascript(2)

    1.延迟脚本defer 在<script>元素中设置defer属性,相当于告诉浏览器立即下载,但是延迟执行.<script>中的脚本会延迟到浏览器遇到</html> ...

  6. [deviceone开发]-QQ分享、微信分享和新浪微博分享

    一.简介 该demo主要实现QQ分享.微信分享和新浪微博分享.(调试包请到论坛扫描对应二维码下载) 二.效果图 三.相关讨论 http://bbs.deviceone.net/forum.php?mo ...

  7. ssh框架搭建的基本步骤(以及各部分作用)

    ssh框架搭建的基本步骤(以及各部分作用)     一.首先,明确spring,struts,hibernate在环境中各自的作用.   struts: 用来响应用户的action,对应到相应的类进行 ...

  8. jQuery 重要的知识点归纳

    jQuery 对象 jQuery 对象就是通过 jQuery 包装 DOM 对象后产生的对象. jQuery 对象是 jQuery 独有的. 只有 jQuery 对象才能使用 jQuery 的方法,在 ...

  9. 设置时间 new Date

    1.标准格式下的时间是object ,操作时可以通过 var cDate=new Date(startTime.getTime());来复制当前日期避免操作给初始日期带来影响 2. 以月为单位计算想要 ...

  10. 使用Javascript来编写贪食蛇(零基础)

      引用的东西都很基础,注释也很多,这里就不多说了. <head> <meta http-equiv="Content-Type" content="t ...