本篇将会用一个demo来展示Activiti工作流具体的体现。
一、demo业务分析
以HelloWorld程序为例。
首先说一下业务流程,员工张三提交了一个申请,然后由部门经理李四审核,审核通过后再由总经理王五审核,通过则张三申请成功。接下来用Actitivi工作流来实现业务。
二、新建项目
首先新建一个Activiti项目,目录结构如下。
三、画流程图
在diagrams下新建一个Activiti Diagram:右击diagrams->new->others->Activiti Diagram
然后画流程图:
指派各活动节点的分派人:分别为张三,李四,王五。
四、配置环境
引jar包,建数据库建表,配置日志文件,参考上篇博文《Activiti工作流的环境配置》
五、新建HelloWorld类
配置好环境后,新建HelloWorld类,代码如下。
-
<span style=
"font-size:18px;">
package cn.itcast.a_helloworld;
-
-
-
import java.util.List;
-
-
import org.activiti.engine.ProcessEngine;
-
import org.activiti.engine.ProcessEngines;
-
import org.activiti.engine.repository.Deployment;
-
import org.activiti.engine.runtime.ProcessInstance;
-
import org.activiti.engine.task.Task;
-
import org.junit.Test;
-
-
public
class HelloWorld {
-
-
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
-
-
/**部署流程定义*/
-
@Test
-
public void deploymentProcessDefinition(){
-
Deployment deployment = processEngine.getRepositoryService()
//与流程定义和部署对象相关的Service
-
.createDeployment()
//创建一个部署对象
-
.name(
"helloworld入门程序")
//添加部署的名称
-
.addClasspathResource(
"diagrams/helloword.bpmn")
//从classpath的资源中加载,一次只能加载一个文件
-
.addClasspathResource(
"diagrams/helloword.png")
//从classpath的资源中加载,一次只能加载一个文件
-
.deploy();
//完成部署
-
System.out.println(
"部署ID:"+deployment.getId());
//1
-
System.out.println(
"部署名称"+deployment.getName());
//helloworld入门程序
-
-
}
-
-
/**启动流程实例**/
-
@Test
-
public void startProcessInstance(){
-
//流程定义的key
-
String processDefinitionKey =
"helloworld";
-
ProcessInstance pi = processEngine.getRuntimeService()
//与正在执行 的流程实例和执行对象相关的Service
-
.startProcessInstanceByKey(processDefinitionKey);
//使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动
-
System.out.println(
"流程实例ID:"+pi.getId());
-
System.out.println(
"流程定义ID:"+pi.getProcessDefinitionId());
-
}
-
-
/**查询当前人的个人任务*/
-
@Test
-
public void findMyPersonalTask(){
-
String assignee =
"张三";
-
List<Task> list = processEngine.getTaskService()
//与正在执行的任务管理相关的Service
-
.createTaskQuery()
//创建任务查询
-
.taskAssignee(assignee)
//指定个人任查询,指定办理人
-
.list();
-
if(list!=
null && list.size()>
0){
-
for(Task task:list){
-
System.out.println(
"任务ID:"+task.getId());
-
System.out.println(
"任务名称:"+task.getName());
-
System.out.println(
"任务的创建时间:"+task.getCreateTime());
-
System.out.println(
"任务的办理人:"+task.getAssignee());
-
System.out.println(
"流程实例ID:"+task.getProcessInstanceId());
-
System.out.println(
"执行对象ID:"+task.getExecutionId());
-
System.out.println(
"流程定义ID:"+task.getProcessDefinitionId());
-
System.out.println(
"############################################");
-
}
-
}
-
}
-
-
/**完成我的任务*/
-
@Test
-
public void completeMyPersonalTask(){
-
//任务ID
-
String taskId =
"11402";
-
processEngine.getTaskService()
//与正在执行的任务管理相关的Service
-
.complete(taskId);
-
System.out.println(
"完成任务:任务ID:"+taskId);
-
}
-
}
-
</span>
分开来讲:
1、部署流程定义
-
<span style=
"font-size:18px;">
/**部署流程定义*/
-
@Test
-
public void deploymentProcessDefinition(){
-
Deployment deployment = processEngine.getRepositoryService()
//与流程定义和部署对象相关的Service
-
.createDeployment()
//创建一个部署对象
-
.name(
"helloworld入门程序")
//添加部署的名称
-
.addClasspathResource(
"diagrams/helloword.bpmn")
//从classpath的资源中加载,一次只能加载一个文件
-
.addClasspathResource(
"diagrams/helloword.png")
//从classpath的资源中加载,一次只能加载一个文件
-
.deploy();
//完成部署
-
System.out.println(
"部署ID:"+deployment.getId());
//1
-
System.out.println(
"部署名称"+deployment.getName());
//helloworld入门程序
-
-
</span>
执行完后,4张表中的数据:
1)act_re_deployment (部署信息表)
2)act_re_procdef(流程定义数据表)
3)act_ge_bytearray(二进制数组表)
4)act_ge_property(属性数据表)
2、启动流程实例
-
<span style=
"font-size:18px;">
/启动流程实例/
-
@Test
-
public void startProcessInstance(){
-
//流程定义的key
-
String processDefinitionKey =
"helloworld";
-
ProcessInstance pi = processEngine.getRuntimeService()
//与正在执行 的流程实例和执行对象相关的Service
-
.startProcessInstanceByKey(processDefinitionKey);
//使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动
-
System.out.println(
"流程实例ID:"+pi.getId());
//流程实例ID 101
-
System.out.println(
"流程定义ID:"+pi.getProcessDefinitionId());
//流程定义ID
-
}</span>
执行完后四张表中的数据:
1)act_ru_execution(运行时流程执行实例表)
2)act_ru_task(运行时任务节点表)
3)act_identitylink(运行时流程人员表)
4)act_hi_taskinst(历史任务实例表)
5)act_hi_procinst(历史流程实例表)
6)act_hi_identitylink(历史流程人员表)
7)act_hi_actinst(历史节点表)
8)act_ge_property
从上图中可以看出变化,next.dbid的VALUE_值由原来的101变为201,REV_由原来的2变为3。
3、查询当前人的个人任务
-
<span style=
"font-size:18px;">
/*查询当前人的个人任务/
-
@Test
-
public void findMyPersonalTask(){
-
String assignee =
"张三";
-
List<Task> list = processEngine.getTaskService()
//与正在执行的任务管理相关的Service
-
.createTaskQuery()
//创建任务查询
-
.taskAssignee(assignee)
//指定个人任查询,指定办理人
-
.list();
-
if(list!=
null && list.size()>
0){
-
for(Task task:list){
-
System.out.println(
"任务ID:"+task.getId());
-
System.out.println(
"任务名称:"+task.getName());
-
System.out.println(
"任务的创建时间:"+task.getCreateTime());
-
System.out.println(
"任务的办理人:"+task.getAssignee());
-
System.out.println(
"流程实例ID:"+task.getProcessInstanceId());
-
System.out.println(
"执行对象ID:"+task.getExecutionId());
-
System.out.println(
"流程定义ID:"+task.getProcessDefinitionId());
-
System.out.println(
"############################################");
-
}
-
}
-
}</span>
执行完后,能够从运行时任务节点表中查询出相关的信息并显示出来。与上面同理,act_ge_property的两个值分别又变了。
4、完成我的任务
-
<span style=
"font-size:18px;">
/*完成我的任务/
-
@Test
-
public void completeMyPersonalTask(){
-
//任务ID
-
String taskId =
"104";
//运行时任务ID
-
processEngine.getTaskService()
//与正在执行的任务管理相关的Service
-
.complete(taskId);
-
System.out.println(
"完成任务:任务ID:"+taskId);
-
}</span>
执行完后,表的变化。
1)act_ru_task
从上表中可以看出完成张三的任务后,张三的任务消失,李四的任务显示在表中。
2)act_ru_identitylink
从上表中可以看出多了一条李四的用户数据。
3)act_hi_actinst
从上表中可以看出多了一条李四的节点数据。
同理act_hi_identitylink也会多一条李四的用户数据, ac_hi_taskinst多一条李四的任务数据。
然后完成李四的任务,到王五同理;完成王五的任务后张三申请成功,同理,但是运行时表的数据会全部清除,act_hi_procinst的结束相关字段会更新。至此,整个申请结束。
这是Activiti工作流的一个小demo,大家可以参照着实践一下。下面是本demo及更多demo源码下载的地址:http://download.csdn.net/detail/u013037201/9559857