一、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内容如下图所示:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <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"> 3 <process id="test" name="My process" isExecutable="true"> 4 <startEvent id="start" name="Start"></startEvent> 5 <endEvent id="end" name="End"></endEvent> 6 <userTask id="usertask1" name="step1" activiti:assignee="kermit"></userTask> 7 <userTask id="usertask2" name="step2" activiti:candidateUsers="kermit,gonzo"></userTask> 8 <userTask id="usertask3" name="step3" activiti:candidateGroups="management,accountancy"></userTask> 9 <sequenceFlow id="flow1" sourceRef="start" targetRef="usertask1"></sequenceFlow> 10 <sequenceFlow id="flow2" sourceRef="usertask1" targetRef="usertask2"></sequenceFlow> 11 <sequenceFlow id="flow3" sourceRef="usertask2" targetRef="usertask3"></sequenceFlow> 12 <sequenceFlow id="flow4" sourceRef="usertask3" targetRef="end"></sequenceFlow> 13 </process> 14 <bpmndi:BPMNDiagram id="BPMNDiagram_test"> 15 <bpmndi:BPMNPlane bpmnElement="test" id="BPMNPlane_test"> 16 <bpmndi:BPMNShape bpmnElement="start" id="BPMNShape_start"> 17 <omgdc:Bounds height="35.0" width="35.0" x="20.0" y="129.0"></omgdc:Bounds> 18 </bpmndi:BPMNShape> 19 <bpmndi:BPMNShape bpmnElement="end" id="BPMNShape_end"> 20 <omgdc:Bounds height="35.0" width="35.0" x="610.0" y="129.0"></omgdc:Bounds> 21 </bpmndi:BPMNShape> 22 <bpmndi:BPMNShape bpmnElement="usertask1" id="BPMNShape_usertask1"> 23 <omgdc:Bounds height="55.0" width="105.0" x="110.0" y="119.0"></omgdc:Bounds> 24 </bpmndi:BPMNShape> 25 <bpmndi:BPMNShape bpmnElement="usertask2" id="BPMNShape_usertask2"> 26 <omgdc:Bounds height="55.0" width="105.0" x="290.0" y="119.0"></omgdc:Bounds> 27 </bpmndi:BPMNShape> 28 <bpmndi:BPMNShape bpmnElement="usertask3" id="BPMNShape_usertask3"> 29 <omgdc:Bounds height="55.0" width="105.0" x="450.0" y="119.0"></omgdc:Bounds> 30 </bpmndi:BPMNShape> 31 <bpmndi:BPMNEdge bpmnElement="flow1" id="BPMNEdge_flow1"> 32 <omgdi:waypoint x="55.0" y="146.0"></omgdi:waypoint> 33 <omgdi:waypoint x="110.0" y="146.0"></omgdi:waypoint> 34 </bpmndi:BPMNEdge> 35 <bpmndi:BPMNEdge bpmnElement="flow2" id="BPMNEdge_flow2"> 36 <omgdi:waypoint x="215.0" y="146.0"></omgdi:waypoint> 37 <omgdi:waypoint x="290.0" y="146.0"></omgdi:waypoint> 38 </bpmndi:BPMNEdge> 39 <bpmndi:BPMNEdge bpmnElement="flow3" id="BPMNEdge_flow3"> 40 <omgdi:waypoint x="395.0" y="146.0"></omgdi:waypoint> 41 <omgdi:waypoint x="450.0" y="146.0"></omgdi:waypoint> 42 </bpmndi:BPMNEdge> 43 <bpmndi:BPMNEdge bpmnElement="flow4" id="BPMNEdge_flow4"> 44 <omgdi:waypoint x="555.0" y="146.0"></omgdi:waypoint> 45 <omgdi:waypoint x="610.0" y="146.0"></omgdi:waypoint> 46 </bpmndi:BPMNEdge> 47 </bpmndi:BPMNPlane> 48 </bpmndi:BPMNDiagram> 49 </definitions>
2、代码示例
工程使用maven构建,pom.xml文件内容如下:
1 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
2 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
3 <modelVersion>4.0.0</modelVersion>
4
5 <groupId>com.shh</groupId>
6 <artifactId>activitytest</artifactId>
7 <version>0.0.1-SNAPSHOT</version>
8 <packaging>jar</packaging>
9
10 <name>activitytest</name>
11 <url>http://maven.apache.org</url>
12
13 <properties>
14 <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
15 <activiti-version>5.18.0</activiti-version>
16 </properties>
17 <dependencies>
18 <dependency>
19 <groupId>org.activiti</groupId>
20 <artifactId>activiti-engine</artifactId>
21 <version>${activiti-version}</version>
22 </dependency>
23 <dependency>
24 <groupId>org.activiti</groupId>
25 <artifactId>activiti-spring</artifactId>
26 <version>${activiti-version}</version>
27 </dependency>
28 <dependency>
29 <groupId>org.codehaus.groovy</groupId>
30 <artifactId>groovy-all</artifactId>
31 <version>2.0.4</version>
32 </dependency>
33 <dependency>
34 <groupId>mysql</groupId>
35 <artifactId>mysql-connector-java</artifactId>
36 <version>5.1.35</version>
37 </dependency>
38 <dependency>
39 <groupId>org.slf4j</groupId>
40 <artifactId>slf4j-api</artifactId>
41 <version>1.7.2</version>
42 </dependency>
43 <dependency>
44 <groupId>org.slf4j</groupId>
45 <artifactId>slf4j-jdk14</artifactId>
46 <version>1.7.2</version>
47 </dependency>
48 <dependency>
49 <groupId>junit</groupId>
50 <artifactId>junit</artifactId>
51 <version>4.11</version>
52 </dependency>
53
54 <dependency>
55 <groupId>org.springframework</groupId>
56 <artifactId>spring-core</artifactId>
57 <version>3.2.2.RELEASE</version>
58 </dependency>
59 <dependency>
60 <groupId>org.springframework</groupId>
61 <artifactId>spring-beans</artifactId>
62 <version>3.2.2.RELEASE</version>
63 </dependency>
64 <dependency>
65 <groupId>org.springframework</groupId>
66 <artifactId>spring-test</artifactId>
67 <version>3.2.2.RELEASE</version>
68 </dependency>
69
70 <dependency>
71 <groupId>org.springframework</groupId>
72 <artifactId>spring-context</artifactId>
73 <version>3.2.2.RELEASE</version>
74 </dependency>
75 <dependency>
76 <groupId>org.springframework</groupId>
77 <artifactId>spring-context-support</artifactId>
78 <version>3.2.2.RELEASE</version>
79 </dependency>
80 <dependency>
81 <groupId>org.springframework</groupId>
82 <artifactId>spring-tx</artifactId>
83 <version>3.2.2.RELEASE</version>
84 </dependency>
85 <dependency>
86 <groupId>org.springframework</groupId>
87 <artifactId>spring-orm</artifactId>
88 <version>3.2.2.RELEASE</version>
89 </dependency>
90 </dependencies>
91 </project>
spring配置文件activiti.cfg.xml内容如下:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xsi:schemaLocation="http://www.springframework.org/schema/beans 5 http://www.springframework.org/schema/beans/spring-beans.xsd"> 6 <bean id="processEngineConfiguration" 7 class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration"> 8 <property name="databaseSchemaUpdate" value="true" /> 9 <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti?autoReconnect=true&useUnicode=true&characterEncoding=utf8" /> 10 <property name="jdbcDriver" value="com.mysql.jdbc.Driver" /> 11 <property name="jdbcUsername" value="root" /> 12 <property name="jdbcPassword" value="" /> 13 <property name="jobExecutorActivate" value="true" /> 14 </bean> 15 </beans>
测试类TestActiviti代码如下:
1 package com.shh.test;
2
3 import java.util.List;
4
5 import org.activiti.engine.ProcessEngine;
6 import org.activiti.engine.ProcessEngineConfiguration;
7 import org.activiti.engine.RepositoryService;
8 import org.activiti.engine.RuntimeService;
9 import org.activiti.engine.TaskService;
10 import org.activiti.engine.repository.Deployment;
11 import org.activiti.engine.task.Task;
12 import org.junit.Before;
13 import org.junit.Test;
14
15 /**
16 * 测试流程
17 * @author 20150205
18 *
19 */
20 public class TestActiviti {
21 ProcessEngine processEngine = null;
22 RepositoryService repositoryService = null;
23 RuntimeService runtimeService = null;
24 TaskService taskService = null;
25
26 @Before
27 public void init() {
28 //加载spring配置文件,创建 ProcessEngine
29 processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("activiti.cfg.xml")
30 .buildProcessEngine();
31 repositoryService = processEngine.getRepositoryService();
32 runtimeService = processEngine.getRuntimeService();
33 taskService = processEngine.getTaskService();
34 }
35
36
37 /**
38 * 部署流程定义加载test.bpmn文件
39 */
40 @Test
41 public void deploy(){
42 Deployment deployment = repositoryService.createDeployment().addClasspathResource("diagrams/test.bpmn").deploy();
43 String id = deployment.getId();
44 System.out.println("***************部署流程定义完成***************" + id);
45 }
46
47 /**
48 * 启动一个请假流程
49 */
50 @Test
51 public void start() {
52 for(int i = 0 ; i < 5; i++){
53 String processId = runtimeService.startProcessInstanceByKey("test").getId();
54 System.out.println("***************启动第" + i + "个请假流程完成***************" + processId);
55 }
56 }
57
58
59 /**
60 * 第一步
61 */
62 @Test
63 public void step1(){
64 System.out.println("***************step1流程开始***************");
65 List<Task> tasks = taskService.createTaskQuery().taskAssignee("kermit").list();//kermit的任务
66 List<Task> tasks2 = taskService.createTaskQuery().taskAssignee("gonzo").list();//gonzo的任务
67 System.out.println(tasks.size());
68 System.out.println(tasks2.size());//指定了kermit,所以gonzo的任务数量为0
69
70 for (Task task : tasks) {
71 System.out.println("kermit的任务taskname:" + task.getName() + ",id:" + task.getId());//任务的name与id
72 System.out.println(task.getAssignee());//任务拥有者
73 System.out.println(task.getProcessInstanceId());//流程实例id
74 System.out.println(task.getProcessDefinitionId());//流程定义id
75 taskService.complete(task.getId());//完成任务
76 }
77
78 System.out.println("kermit的任务数量:" + taskService.createTaskQuery().taskAssignee("kermit").count());
79 System.out.println("***************step1流程结束***************");
80 }
81
82 /**
83 * 第二步
84 */
85 @Test
86 public void step2(){
87 System.out.println("***************step2流程开始***************");
88 List<Task> tasks = taskService.createTaskQuery().taskCandidateUser("kermit").list();//kermit可领取的任务
89 List<Task> tasks2 = taskService.createTaskQuery().taskCandidateUser("gonzo").list();//gonzo可领取的任务
90 System.out.println(tasks.size());
91 System.out.println(tasks2.size());
92
93 for (int i = 0 ; i < tasks.size(); i++) {
94 Task task = tasks.get(i);
95 System.out.println("任务taskname:" + task.getName() + ",id:" + task.getId());//任务的name与id
96 if(i % 2 == 0){
97 taskService.claim(task.getId(), "kermit");//kermit领取任务
98 }else{
99 taskService.claim(task.getId(), "gonzo");//gonzo领取任务
100 }
101 }
102
103 tasks = taskService.createTaskQuery().taskAssignee("kermit").list();
104 tasks2 = taskService.createTaskQuery().taskAssignee("gonzo").list();
105 System.out.println("kermit的任务数量:" + tasks.size());
106 System.out.println("gonzo的任务数量:" + tasks2.size());
107
108 for(Task t : tasks){
109 taskService.complete(t.getId());//完成任务
110 }
111 for(Task t : tasks2){
112 taskService.complete(t.getId());//完成任务
113 }
114 tasks = taskService.createTaskQuery().taskAssignee("kermit").list();
115 tasks2 = taskService.createTaskQuery().taskAssignee("gonzo").list();
116 System.out.println("kermit的任务数量:" + tasks.size());
117 System.out.println("gonzo的任务数量:" + tasks2.size());
118 System.out.println("***************step2流程结束***************");
119 }
120
121 @Test
122 public void step3(){
123 System.out.println("***************step3流程开始***************");
124 List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("management").list();//management组可领取的任务
125 List<Task> tasks2 = taskService.createTaskQuery().taskCandidateGroup("accountancy").list();//accountancy组可领取的任务
126 System.out.println(tasks.size());
127 System.out.println(tasks2.size());
128
129 for (int i = 0 ; i < tasks.size(); i++) {
130 Task task = tasks.get(i);
131 System.out.println("任务taskname:" + task.getName() + ",id:" + task.getId());//任务的name与id
132 if(i % 2 == 0){
133 taskService.claim(task.getId(), "kermit");
134 }else{
135 taskService.claim(task.getId(), "gonzo");
136 }
137 }
138 tasks = taskService.createTaskQuery().taskAssignee("kermit").list();
139 tasks2 = taskService.createTaskQuery().taskAssignee("gonzo").list();
140 System.out.println("kermit的任务数量:" + tasks.size());
141 System.out.println("gonzo的任务数量:" + tasks2.size());
142
143 for(Task t : tasks){
144 taskService.complete(t.getId());//完成任务
145 }
146 for(Task t : tasks2){
147 taskService.complete(t.getId());//完成任务
148 }
149 tasks = taskService.createTaskQuery().taskAssignee("kermit").list();
150 tasks2 = taskService.createTaskQuery().taskAssignee("gonzo").list();
151 System.out.println("kermit的任务数量:" + tasks.size());
152 System.out.println("gonzo的任务数量:" + tasks2.size());
153
154 System.out.println("***************step3流程结束***************");
155 }
156 }
依次执行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流程结束***************
来源:https://www.cnblogs.com/always-online/p/4699702.html