初次接触工作流是在OA中,现在再为简略的总结一下,这篇文章要说的是JBPM宏观结构、简单实例、扩展使用三部分。
Java Business Process Management,覆盖了业务流程管理、工作流、服务协作等领域,并且是一个开源的、灵活的、易扩展的流程语言框架。
简单的说,JBPM是一个框架,结合hibernate、数据库、流程图、描述语言等,专门处理与工作流有关的问题。
JBoss jBPM Process Definition Language,用于构建jBPM的流程语言,既然是语言,必然要有控制结构、语法、变量等概念,它把一个工作流看作是UML状态图,jPdl的作用就是定义状态图的每个部分,如起始、结束状态。
它的语言的作用可以是通过拖拽组件或编辑XML文件的方式实现,如通过流程传递,实现顺序结构,详见以下实例。
以一张图的方式展示JBPM的核心内容,如下:
如上所示,JBPM按照既定的流程图,通过封装的8个核心对象,以Hibernate的方式操作数据库,将各个流程的操作持久化,保存到数据库中。
如有兴趣,可以按照流程的传递,去跟踪流程和任务在数据中转移的顺序,加深对JBPM的了解。
<?xml version="1.0" encoding="UTF-8"?> <process key="test" name="test1" xmlns="http://jbpm.org/4.4/jpdl"> <start g="284,14,48,48" name="start1"> <transition g="-52,-22" name="提交给一级主管" to="一级主管审批"/> </start> <task assignee="A" g="262,107,92,52" name="一级主管审批"> <transition g="-68,-8" name="提交到二级主管" to="二级主管审批"/> </task> <task assignee="B" g="263,193,92,52" name="二级主管审批"> <transition g="-37,-11" name="通过" to="end1"/> </task> <end g="286,281,48,48" name="end1"/> </process>
用于创建各个对象。
package com.tgb.jbpm; import junit.framework.TestCase; import org.jbpm.api.Configuration; import org.jbpm.api.ExecutionService; import org.jbpm.api.ProcessEngine; import org.jbpm.api.RepositoryService; import org.jbpm.api.TaskService; public class ServiceFactory extends TestCase { private ProcessEngine processEngine; private RepositoryService repositoryService; private ExecutionService executionService; private TaskService taskService; /*** * 得到各个服务对象 */ protected void startUp(){ processEngine=Configuration.getProcessEngine(); repositoryService=processEngine.getRepositoryService(); executionService=processEngine.getExecutionService(); taskService=processEngine.getTaskService(); } //此处省略getter和setter }
测试各个流程步骤所产生的结果。
package com.tgb.jbpm; import java.util.List; import org.jbpm.api.ProcessInstance; import org.jbpm.api.task.Task; public class TestFlow extends ServiceFactory { protected String instanceId; protected String taskId; /*** * 按步骤的流程 */ public void flow(){ //初始化服务 startUp(); //部署工作流 deploy(); //创建工作流实例 createInstanceByKey(); //查询A下的任务 getTasksByPersonId(); //结束任务“一级主管审批” completeTaskById(); //查询工作流实例所在的任务实例 getCurrentTaskByInstanceId(); } /*** * 部署工作流 */ public void deploy(){ getRepositoryService().createDeployment() .addResourceFromClasspath("test1.jpdl.xml").deploy(); System.out.println("工作流已经成功部署!"); } /*** * 创建流程实例,保存实例Id */ public void createInstanceByKey() { ProcessInstance processInstance=getExecutionService() .startProcessInstanceByKey("test"); instanceId=processInstance.getId(); System.out.println("已成功创建新实例,Id为:"+processInstance.getId()); } /**** * 得到任务实例信息 */ public void getTasksByPersonId(){ List<Task> task=getTaskService().findPersonalTasks("A"); taskId=task.get(0).getId(); System.out.println("任务数量:"+task.size()); System.out.println("任务名称:"+task.get(0).getName()); System.out.println("任务人员:"+task.get(0).getAssignee()); System.out.println("任务ID:"+task.get(0).getId()); } /*** * 查询实例所在任务节点 */ public void getCurrentTaskByInstanceId(){ startUp(); String activity=getExecutionService().createProcessInstanceQuery() .processInstanceId(instanceId) .uniqueResult().toString(); System.out.println("当前所在结点为:"+activity); } /*** * 根据流程实例id结束任务 */ public void completeTaskById(){ startUp(); getTaskService().completeTask(taskId); } }
工作流已经成功部署! 已成功创建新实例,Id为:test.20007 任务数量:2 任务名称:一级主管审批 任务人员:A 任务ID:10002 当前所在结点为:execution[test.20007]
以上是最简单的顺序结构,你可以使用更复杂的结构,如:
仔细看会发现,上述的代码写的很"死",不只是代码,工作流的定义文件中,流程"A"和"B"等也定义的很“死”,难道JBPM以如此不灵活的方式应对复杂的工作流程?当然不是,这也是下面要说的内容。
文章篇幅有限,不再把JBPM的每种使用和注意事项都写一遍,但会提供以下思路:
以上即是对JBPM大面上的总结,实例也可满足简单的使用,更多细节问题,有待在实战中发现。
推荐:轻量级思维导图软件Blumind(803KB)。