流程引擎的入门级使用教学
一、下载activiti安装包
链接:https://pan.baidu.com/s/1-_XjIsuZfhiEZn6iLul6-Q 密码:mfyk (这是其他网友的链接)
二、eclipse安装activiti插件(我使用的是离线安装方式,在线安装我这也没试过!)
1、将安装包解压,解压文件目录如下:有四个jar包和一个压缩包
2、将四个jar包放在eclipse的features目录中(我的开发工具用的是eclipse,sts也是一样)
3、然后打开eclipse,鼠标点击help,选中install new software
选中install software之后,点击add,出现如下界面
4、Name: Activiti (给你安装的插件取个名字),取好之后选中local,选中安装包解压的目录,点击确定,再点击OK。
5、将如下勾选框选中,然后一直next,一直到finish(当然中间会让你勾选同意选项)。
6、安装完成后,重启eclipse,重启后点击file--->>new-->other,看到如下图示,说明安装完成
三、开始使用进行编程测试
1、新建一个maven项目,项目目录如下:
2、test.bpmn文件代码如下(新建.bpmn文件是以画图的形式表现的,要粘贴代码可以右键点击test.bpmn文件----->>open whit--------->>XML editor):
<?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>
3、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>
4、activiti.cfg.xml文件如下配置,其中 <property name="jdbcPassword" value="" /> 的value值是你本地数据库的面。
<?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&useUnicode=true&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>
5、配置都做好之后,我们开始写测试类来测试效果,测试类代码如下:
package activitiTest.Demo;
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();
Deployment deployment = repositoryService.createDeployment().addClasspathResource("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流程结束***************");
}
}
四、数据库配置
1、使用Navicat创建一个名为activiti的数据库(不需要建表,运行项目时自动生成)
五、测试类运行效果如下:
***************部署流程定义完成***************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流程结束***************
千里之行,始于足下