工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现”。
工作流管理系统(WfMS,Workflow Management System)的主要功能是通过计算机技术的支持去定义、执行和管理工作流,协调工作流执行过程中工作之间以及群体成员之间的信息交互。工作流需要依靠工作流管理系统来实现。工作流管理系统是定义、创建、执行工作流的系统,应能提供以下三个方面的功能支持:
1. 定义工作流:包括具体的活动、规则等
2. 运行控制功能:在运行环境中管理工作流过程,对工作流过程中的活动进行调度
3. 运行交互功能:指在工作流运行中,WfMS与用户(活动的参与者)及外部应用程序工具交互的功能。
一、管理流程
部署(添加)删除
查询(查询所有、自定义条件查询)
获取部署添加的文件信息(查看流程图)
* 没有更新操作!策略为:重新部署 + 版本递增。
二、执行流程
启动流程实例
查询我的任务列表
办理任务
直接向后执行一步
===========================================
部署对象 Deployment
表示一次部署的多个文件的信息。
对应的表:
jbpm4_deployment
jbpm4_lob
流程定义 ProcessDefinition
表示一个工作流程,包含每个环节的详细信息。
这是解析.jpdl.xml文件得到的数据。
此类没有对应的表,他对应的是.jpdl.xml文件。
执行对象 Execution
表示一个执行的路径(分支)。最大的分支就是从Start到End的那个。
最大的分支称为Root Execution 也称为 ProcessInstance。
对应的表:
jbpm4_execution 正在执行的信息表
jbpm4_hist_procinst 已经执行完的历史信息表
流程实例 ProcessInstance
表示按某流程定义执行的所有执行时的信息。
ProcessInstance就是Execution对象(的子类型)
任务 Task
在执行流程的过程中,在Task环节生成的任务信息。
对应的表:
jbpm4_task 正在执行的信息表
jbpm4_hist_task已经执行完的历史信息表
示例代码:
/**
* 管理流程定义有关的操作
* 部署(添加)
* 删除
* 查询(查询所有、自定义条件查询)
* 获取部署添加的文件信息(查看流程图)
* !!没有更新操作!策略为:重新部署 + 版本递增。
*
*/
public class ProcessDefinitionTest {
// 返回单例的ProcessEngine实例,使用的是默认的配置文件(jbpm.cfg.xml)
private ProcessEngine processEngine = Configuration.getProcessEngine();
// 部署(添加)
@Test
public void testDeploy() throws Exception {
String deploymentId = processEngine.getRepositoryService()//
.createDeployment()// 创建一个部署对象
.addResourceFromClasspath("helloworld/helloworld.jpdl.xml")// 添加一个要部署的文件
.addResourceFromClasspath("helloworld/helloworld.png")// 添加一个要部署的文件
.deploy(); // 执行部署操作
System.out.println("部署成功:deploymentId = " + deploymentId);
}
// 部署(把多个文件打包为一个zip一起部署)
@Test
public void testDeploy_zip() throws Exception {
// 准备
ZipInputStream zipInputStream = new ZipInputStream(new FileInputStream("d:/helloworld.zip"));
// 部署
String deploymentId = processEngine.getRepositoryService()//
.createDeployment()// 创建一个部署对象
.addResourcesFromZipInputStream(zipInputStream)// 指定zip流
.deploy(); // 执行部署操作
System.out.println("部署成功:deploymentId = " + deploymentId);
}
// 删除
@Test
public void testDelete() throws Exception {
// // 删除指定的部署对象,如果有关联的信息,就报错
// processEngine.getRepositoryService().deleteDeployment(deploymentId);
// // 删除指定的部署对象,如果有关联的信息,就一并删除
// processEngine.getRepositoryService().deleteDeploymentCascade(deploymentId);
String deploymentId = "40001";
processEngine.getRepositoryService().deleteDeploymentCascade(deploymentId);
}
// 查询流程定义(查询所有、自定义条件查询)
@Test
public void testFindAllProcessDefinition() throws Exception {
// 查询
List<ProcessDefinition> list = processEngine.getRepositoryService()//
.createProcessDefinitionQuery()//
// 过滤条件
// .processDefinitionId(processDefinitionId);
// .deploymentId(deploymentId)
// .processDefinitionKey(key)
// .processDefinitionName(name)
// 排序条件
// .orderAsc(property)
// .orderDesc(property)
// .orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)//
// 执行查询得到结果
// .page(firstResult, maxResults)
// .list()
// .count()
// .uniqueResult()
.list();
// 显示
for (ProcessDefinition pd : list) {
System.out.println("id=" + pd.getId()// 格式为:{key}-{version}
+ ", name=" + pd.getName()// .jpdl.xml中根元素的name属性的值。
+ ", key=" + pd.getKey()// .jpdl.xml中根元素的key属性的值。如果不写,默认为name属性的值。
+ ", version=" + pd.getVersion()// .jpdl.xml中根元素的version属性的值。如果不写,默认的效果为同名称的第一个version为1,以后的就递增。(一般不要写)
+ ", deploymentId=" + pd.getDeploymentId()); // 所属的部署对象的id
}
}
// 获取部署时添加的文件信息(查看流程图)
@Test
public void testGetProcessImage() throws Exception {
String deploymentId = "50001";
String resourceName = "helloworld/helloworld.png";
// 获取指定的部署对象中的所有的文件名称
Set<String> nameSet = processEngine.getRepositoryService().getResourceNames(deploymentId);
System.out.println("所有的文件:");
for (String name : nameSet) {
System.out.println("\t" + name);
}
// 获取指定的部署对象中的指定名称的文件内容
InputStream in = processEngine.getRepositoryService().getResourceAsStream(deploymentId, resourceName);
// 存到d:/中
FileOutputStream out = new FileOutputStream("d:/process.png");
byte[] buf = new byte[1024];
for (int len = -1; (len = in.read(buf)) != -1;) {
out.write(buf, 0, len);
}
in.close();
out.close();
}
}
/**
* 执行流程实例有关的操作
* 启动流程实例
* 查询我的任务列表
* 办理任务
* 直接向后执行一步
*/
public class ProcessInstanceTest {
private ProcessEngine processEngine = Configuration.getProcessEngine();
// 启动流程实例
@Test
public void testStartProcessInstance() throws Exception {
// 使用指定的流程定义启动流程实例(指定名称并且是指定的version)
// processEngine.getExecutionService().startProcessInstanceById("helloworld-3");
// 使用指定key的最新版本的流程定义启动一个流程实例
ProcessInstance pi = processEngine.getExecutionService().startProcessInstanceByKey("helloworld");
System.out.println("流程实例启动成功,processInstanceId=" + pi.getId() + ", processDefinitionId=" + pi.getProcessDefinitionId());
}
// 查询我的(未完成的)任务列表
@Test
public void testFindMyTaskList() throws Exception {
// 准备
// String userId = "员工";
// String userId = "部门经理";
String userId = "总经理";
// // 查询所有
// List<Task> list = processEngine.getTaskService().findPersonalTasks(userId);
// 分页的查询
List<Task> list = processEngine.getTaskService()//
.createTaskQuery()//
// 过滤条件
.assignee(userId)// 指定办理人是谁,如果不指定办理人,就会查出所有人的任务
// 排序条件
// .orderAsc(TaskQuery.PROPERTY_CREATEDATE)
// 执行查询得到结果
// .count();
// .page(firstResult, maxResults)
.list();
// 显示
for (Task t : list) {
System.out.println("id=" + t.getId()//
+ ", name=" + t.getName()// 任务名称
+ ", assignee=" + t.getAssignee()// 办理人
+ ", createTime=" + t.getCreateTime()// 此任务的创建时间
+ ", executionId=" + t.getExecutionId()); // 所属的执行对象的id
}
}
// 办理任务
@Test
public void testCompleteTask() throws Exception {
String taskId = "140001";
processEngine.getTaskService().completeTask(taskId);
}
// 直接向后执行一步
@Test
public void testSignal() throws Exception {
String executionId = "helloworld.110001";
processEngine.getExecutionService().signalExecutionById(executionId, "to 总经理[审批]");
}
}