首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

jbpm学习札记(五) jbpm不同服务的详细介绍以及使用 走完流程整个生命周期

2012-12-26 
jbpm学习笔记(五) jbpm不同服务的详细介绍以及使用 走完流程整个生命周期上一篇的示例中我们尝试用了jbpm

jbpm学习笔记(五) jbpm不同服务的详细介绍以及使用 走完流程整个生命周期
     上一篇的示例中我们尝试用了jbpm Service API,现在我们仍然详细介绍API。
一,流程引擎对象,ProcessEngine是jbpm4所有Service API之源

在jbpm中各种服务相互依存,但所有的service API都从ProcessEngine中获得,它是由

Configuration类构建的,即工作流引擎根据配置产生。

        ProcessEngine是线程安全的,因此它可以保存在静态变量中,甚至JNDI命名服务

中或者其他重要位置。在应用中,所有线程和请求都可以使用同一个ProcessEngine对象,

以下代码告诉您如何获得ProcessEngine:

   

    ProcessEngine  processEngine=Configuration.getProcessEngine();     

上面代码中的Configuration使用了classpath根目录下的默认配置文件jbpm.cfg.xml创

建一个ProcessEngine。如果你要自定义位置,那么可以这样做:
  
 ProcessEngine processEngine=new Configuration().setResource(“myjbpm.xml”).buildProcessEngine();

      然后,那6个service直接可以用processEngine.getXXX()得到。下面把这6个service描述一下:

    RepositoryService—流程之源服务的借口。提供对流程定义的部署,查询,删除等操作。

    ExecutionService—流程执行服务的借口。提供启动流程实例,“执行”推进,设置流程变量等操作

    ManagementService—流程管理控制服务的接口,提供异步工作(Job)相关的执行和查询操作。

    TaskService—人工任务服务的接口。提供对任务(Task)的创建,提交,查询,保存,删除等操作。

     HistoryService—流程历史服务的接口。提供对流程历史库(即已完成的流程实例归

档)中历史流程实例,历史活动实例等记录的查询操作。还提供诸如某个流程定义中所有活动

的平均持续时间,某个流程定义中某转移的经过次数等数据分析服务。

    IdentityService—身份认证服务的接口。提供对流程用户,用户组以及组成员关系的相关服务

二,发起一个流程实例有这样几种方式
    1,常规方法:
    ProcessInstance    processInstance=executionService.startProcessInstanceByKey(“order”);


    2,指定业务键发起流程实例,假如要对特定的业务实例来说,我们需要将每个流程

实例和一个独特的业务实例关联起来,比如一个保险流程的实例必然需要和一个保险单号关

联,一个订单流程的实例必然需要和一个订单号关联,以便业务上的查询或索引,那么我们就

可以通过为新启动的流程实例分配一个业务键来做到。一个业务键必须在此流程定义所有版本

的流程实例范围内是唯一的。比如以下:

 ProcessInstance processInstance=executionService.startProcessInstanceByKey(“order”,”afei520”);

    在上面种,afei520就是业务键,和特定的业务有关系。


注:最好指定一个业务键发起流程实例,一般情况下,在业务应用中,找到这样的业务键并不
困难,提供一个业务键的好处是可以根据业务来执行流程实例搜索,这是一个最佳实践。

     3,指定变量发起流程实例 如果新的流程实例需要一些输入参数启动,可以将这个参

数放在流程变量里,然后在发起流程时传入流程变量对象。代码如下:

Map<String, Object> valMap = new HashMap<String, Object>();valMap.put("proposer", user);//创建流程实例return          executionService.startProcessInstanceByKey("loan",valMap);



三,任务服务API,这里的任务是指jbpm task活动产生的人机交互业务。假如要展

示一个人的任务列表:

List<Task> tasks=taskService.findPersonalTasks(“afei”);

        一般来说,任务会有一个表单,显示在一些用户界面中如jsp。这个表单需要读写与任务相关的流程数据,一般是通过任务变量的方式。如下代码:

  
String taskId=taskId;   Set<String> varis=taskService.getVariableNames()taskId;   //读取任务变量   Set<String> variableNames=taskService.getVariableNames(checkTask.getId());for(Iterator<String> it=variableNames.iterator();it.hasNext();){System.out.println("task vari:"+it.next());}Map<String,Object> variables=taskService.getVariables(checkTask.getId(),variableNames);System.out.println("variables:"+variables);或自行创建variables=new HashMap<String,Object>();//设置”键值”形式的任务变量Variables.put(“username”,”afei”);Variables.put(“age”,111111);//将变量存入任务taskService.setVariables(taskId,variables);


四, 对于流程,任务,历史的查询是很重要的,从jbpm4开始,流程查询系统由一

组新的API来支持,这组API可以覆盖到大多数您能想到的查询。

比如流程实例查询:
List<ProcessInstance> results=executionService.                         createProcessInstanceQuery().                         processDefinitionId(“my_process_definition”).//流程定义IdnotSuspended().//未挂起Page(0,50).list();//分页  


比如任务的查询:
List<Task> tasks=taskService.createTaskQuery().                         processInstanceId(piId).//流程实例                         assignee(“Alex”).分配给Alex的任务                         page(100,200).//分页                         orderDesc(TaskQuery.PROPERTY_DUEDATE).//根据日期逆向排序                         List();

其他的服务以此类推

五,下面看一个例子。
首先angel.jpdl.xml代码
<?xml version="1.0" encoding="UTF-8"?><process name="angel" xmlns="http://jbpm.org/4.4/jpdl">   <start name="start">      <transition name="to state" to="state"/>   </start>      <!-- state活动是等待活动。需要收到一个外部的执行信号才能流转通过。 -->   <state name="state">      <transition name="to task" to="task"/>   </state>      <!-- task活动是等待活动。在这里被分配给用户afei办理,afei办理完成提交任务后才能流转通过 -->   <task assignee="afei" name="task">      <transition name="to end" to="end"/>   </task>   <end name="end"/>  </process>


Java测试代码:
package org.test;import org.jbpm.api.Execution;import org.jbpm.api.ProcessInstance;import org.jbpm.api.history.HistoryProcessInstance;import org.jbpm.api.history.HistoryTask;import org.jbpm.api.task.Task;import org.jbpm.test.JbpmTestCase;public class AngelTest extends JbpmTestCase {String deploymentId;@Overridepublic void setUp() throws Exception {super.setUp();deploymentId = repositoryService.createDeployment().addResourceFromClasspath("org/test/angel.jpdl.xml").deploy();}@Overridepublic void tearDown() throws Exception {repositoryService.deleteDeploymentCascade(deploymentId);super.tearDown();}public void testAfei() {System.out.println("********testAfei start********");// 使用执行服务:根据已部署流程定义的名称angel,发起流程实例ProcessInstance pi = executionService.startProcessInstanceByKey("angel");// 获取流程实例IDString pid = pi.getId();// 获取当前活动的执行对象Execution executionState = pi.findActiveExecutionIn("state");// 断言当前活动即为stateassertNotNull(executionState);// 使用执行服务:发出执行信号结束当前活动,继续流程的执行executionService.signalExecutionById(executionState.getId());// 使用执行服务:从持久化层中获取“最新”的流程实例对象pi = executionService.findProcessInstanceById(pid);Execution executionTask = pi.findActiveExecutionIn("task");// 断言当前活动即为taskassertNotNull(executionTask);// 使用任务服务:获取用户afei的任务,即task活动产生的任务Task task = taskService.findPersonalTasks("afei").get(0);// 使用任务服务:完成任务taskService.completeTask(task.getId());// 使用历史服务:创建历史任务查询HistoryTask historyTask = historyService.createHistoryTaskQuery().taskId(task.getId()).uniqueResult();// 断言上一步完成的任务已成为历史,即可通过历史任务查询获取之assertNotNull(historyTask);// 断言该流程实例已经结束assertProcessInstanceEnded(pid);// 使用历史服务:创建历史流程实例查询HistoryProcessInstance hpi = historyService.createHistoryProcessInstanceQuery().processInstanceId(pid).uniqueResult();//断言该流程实例已经成为历史,即可通过历史流程实例查询获取它assertNotNull(hpi);//单元测试至此执行完毕System.out.println("********testAfei end********");}}
这个例子主要是进一步看看Service API的功能及其使用场景。这个例子基本上走完了一个流程的完整生命周期,下一篇着重介绍Jbpm的核心————jPDL。

                         

热点排行