JBPM学习(三)--引擎与5个服务

JBPM服务

参考文档:jbpm-4.4\doc\userguide\html_single\index.html
jbpm-4.4\doc\javadocs\index.html

一:流程定义,实例化和执行(Process definition, process instance and executions)


流程定义描述的过程中的步骤。
一个流程实例代表一个特定的应用程序运行的过程定义。
一个流程实例包含了所有的运行状态。最突出的是跟踪当前活动的指针。

二:流程引擎(ProcessEngine)

使用jBPM交互是通过服务实现的。服务接口可以从流程引擎获取到,而流程引擎由Configuration对象建立。

下面我们看看ProcessEngine的集中构建方式:
1:获取默认ProcessEngine对象。
ProcessEngine pe = Configuration.getProcessEngine();
这个是通过静态方法获取的单例对象,它默认会根据jar包中org/jbpm/api/Configuration路径下的
jbpm.cfg.xml文件来配置该对象。看看源码:

public static ProcessEngine getProcessEngine()
    {
        if(singleton == null)
            synchronized(org/jbpm/api/Configuration)
            {
                if(singleton == null)
                    singleton = (new Configuration()).setResource("jbpm.cfg.xml").buildProcessEngine();
            }
        return singleton;
    }

    private static ProcessEngine singleton;
2:实例化一个新的Configuration对象来构建ProcessEngine。
ProcessEngine pe2 = new Configuration().buildProcessEngine();
这个方法和上面一样的,就是不是单例模式罢了。

3:通过自定义的配置文件来构建。
ProcessEngine pe3 = new Configuration().setResource("my-own-configuration-file.xml").buildProcessEngine();

构建完成后,我们还可以设置其他属性,XmlString,InputSource,URL,HibernateSessionFactory或File。
这些我们都可以在spring中实现注入。

三:服务接口。

上面说的有些多了,我们使用流程引擎就是为了获取服务接口对象,这才是重点。
下面涉及的api较多,但是都很重要,想要学习好JBPM,其实就是对这些api的熟练使用。
万里长城才起步,任重道远啊。

RepositoryService repositoryService = processEngine.getRepositoryService();
ExecutionService executionService = processEngine.getExecutionService();
TaskService taskService = processEngine.getTaskService();
HistoryService historyService = processEngine.getHistoryService();
ManagementService managementService = processEngine.getManagementService();

1:流程资源服务RepositoryService。


1-1:发布流程
首先获取NewDeployment对象。

NewDeployment  newDeployment=repositoryService.createDeployment();
NewDeployment可以发布新流程,api文档中提供了多种发布方式:
//从classpath加载流程定义文件(xxx.jpdl.xml)
 NewDeployment	addResourceFromClasspath(java.lang.String resourceName) 
//通过File对象加载
 NewDeployment	addResourceFromFile(java.io.File file) 
//通过输入流加载
 NewDeployment	addResourceFromInputStream(java.lang.String resourceName, java.io.InputStream inputStream) 
//通过字符串加载
 NewDeployment	addResourceFromString(java.lang.String resourceName, java.lang.String string) 
//通过URL加载
 NewDeployment	addResourceFromUrl(java.net.URL url) 
//通过zip文件流加载
 NewDeployment	addResourcesFromZipInputStream(java.util.zip.ZipInputStream zipInputStream) 
然后调用发布的方法.deploy();
例子
repositoryService.createDeployment().addResourceFromClasspath("org/jbpm/config/process.jpdl.xml").deploy(); 
流程部署后,会生成{key}-{version}格式的流程定义ID,如果流程定义文件未指明key和
version,程序将使用流程名称作为key,根据当前数据库存储情况生成version(version = key
的数量+1)。
生成的key将不是数字和字母的字符,替换为下划线。

1-2:删除流程。

repositoryService.deleteDeployment(deploymentId);//流程定义没有执行时

repositoryService.deleteDeploymentCascade(deploymentId);
//级联删除,包含的流程定义,相关的流程实例和他们的历史信息
1-3:查询流程。
List<ProcessDefinition> processDefinitions = repositoryService.createProcessDefinitionQuery().list();
上面是查询所有的流程,当然也可以
根据某些参数来查,只要添加参数就可以了,如下:
List<ProcessDefinition> processDefinitions = repositoryService
		.createProcessDefinitionQuery()
		.processDefinitionId("")//参数是流程定义的id
		.processDefinitionKey("")//参数是流程定义的key
		.processDefinitionName("")//参数是流程定义的name
		.processDefinitionNameLike("")//参数是流程定义的name,进行模糊查询
		.list();//查询

1-4:挂起和回复流程。
repositoryService.resumeDeployment(deploymentId) //恢复
repositoryService.suspendDeployment(deploymentId) //挂起
*****************************************************************************
2:流程执行服务ExecutionService。

ExecutionService管理运行过程中执行。

2-1:启动流程实例。
ProcessInstance  pi1=executionService.startProcessInstanceById("ICL");//根据id
ProcessInstance  pi2=executionService.startProcessInstanceByKey("ICL-1");//根据流程版本

//使用变量启动
Map<String,Object> variables = new HashMap<String,Object>();
variables.put("customer", "John Doe");
variables.put("type", "Accident");
variables.put("amount", new Float(763.74));

ProcessInstance pi3 = 
    executionService.startProcessInstanceByKey("ICL", variables);

2-2:执行等待新号。
当使用一个state活动时,当它到达的状态时,执行过程(或流程实例)将停止,等待一个信号(也叫外部触发器)。 signalExecution方法都可以用于此。
ProcessInstance pi4=executionService.signalExecutionById("");//参数executionId执行id

首选的方式来获得正确的执行是通过一个监听器来捕获state(状态)的活动,如:

<state name="wait">
  <on event="start">
    <event-listener class="org.jbpm.examples.StartExternalWork" />
  </on>
  ...
</state>
有一个可选的(不太推荐的)的方式,来获得流程执行到达时的状态活动。
如果你知道后,jBPM的API调用执行活动已经进入了状态,才获得这个执行的id:
ProcessInstance processInstance = 
  executionService.startProcessInstanceById(processDefinitionId);

Execution execution = processInstance.findActiveExecutionIn("external work");
String executionId = execution.getId();

*****************************************************************************
3:流程任务服务TaskService。


3-1:任务列表
服务TaskService的主要目的是提供访问任务列表。

//查找指定用户的任务列表
List<Task> taskList = taskService.findPersonalTasks("johndoe");
//查找指定组的任务列表
List<Task> groupTaskList = taskService.findGroupTasks("mygroup");

3-2:读写数据
一般来说,任务会提供一个表单,显示在一些用户接口。
表单需要是能够读取和写入相关的任务的数据。

Object obj=taskService.getVariable(taskId, variableName);
Map<String, Object> mp=taskService.getVariables(taskId, variableNames);
Set<String> set=taskService.getVariableNames("");

3-3:完成任务

taskService.completeTask(taskId);
taskService.completeTask(taskId, variables);
taskService.completeTask(taskId, outcome);
taskService.completeTask(taskId, outcome, variables);

该API允许任务完成之前,提供一个map,添加到流程实例。
另外,也可以提供一种“结果”,将被用来确定哪个走向将被选择。逻辑如下:

a)如果一个任务有一个没有name的transition:
If a task has one outgoing transition without a name then:

taskService.getOutcomes() //returns a collection that includes one null value
taskService.completeTask(taskId) //will take that outgoing transition
taskService.completeTask(taskId, null) //will take that outgoing transition
taskService.completeTask(taskId, "anyvalue") //will result in an exception

b)如果一个任务有一个有name的transition:
If a task has one outgoing transition with a name then:

taskService.getOutcomes() //returns a collection that includes only the name of the transition
taskService.completeTask(taskId) //will take the single outgoing transition
taskService.completeTask(taskId, null) //will will result in an exception (as there is no transition without a name)
taskService.completeTask(taskId, "anyvalue") //will result in an exception
taskService.completeTask(taskId, "myName") //will take the transition with the given name


c)如果一个任务拥有多个transition,而其中一个没有name,其他都有name:
If a task has multiple outgoing transitions. One transition has no a name and the other transition have a name:

taskService.getOutcomes() //returns a collection that includes a null value and the names of the other transitions
taskService.completeTask(taskId) //will take the transition without a name
taskService.completeTask(taskId, null) //will take the transition without a name
taskService.completeTask(taskId, "anyvalue")// will result in an exception
taskService.completeTask(taskId, "myName") //will take the 'myName' transition


d)如果一个任务拥有多个transition,并且都有唯一的name:
If a task has multiple outgoing transitions and all of them are uniquely named, then:

taskService.getOutcomes() //returns a collection that includes all the names of all the transitions
taskService.completeTask(taskId) //will result in an exception, since there is no transition without a name
taskService.completeTask(taskId, null) //will result in an exception, since there is no unnamed transition
taskService.completeTask(taskId, "anyvalue") //will result in an exception
taskService.completeTask(taskId, "myName") //will take the 'myName' transition

看上面的说明有些不理解,首先看一个流程定义的文件myprocess.jpdl.xml:

<?xml version="1.0" encoding="UTF-8"?>

<process name="myprocess" xmlns="http://jbpm.org/4.4/jpdl">
   <start name="start1" g="90,129,48,48">
      <transition name="to state1" to="state1" g="-56,-22"/>
   </start>
   <state name="state1" g="307,127,92,52">
      <transition name="to end1" to="end1" g="-50,-22"/>
   </state>
   <end name="end1" g="564,128,48,48"/>
</process>

*****************************************************************************
4:流程历史服务HistoryService。


流程实例的运行时的执行过程中,生成事件。从这些事件中,运行和完成流程的历史信息被收集到历史表中。
HistoryService提供了访问这些信息。

List<HistoryTask> task=historyService.createHistoryTaskQuery().taskId("").list();
List<HistoryProcessInstance> hps=historyService.createHistoryProcessInstanceQuery().processDefinitionId("").list();
List<HistoryActivityInstance> hais=historyService.createHistoryActivityInstanceQuery().processDefinitionId("").activityName("").list();

*****************************************************************************
5:流程管理服务ManagementService。

管理服务通常用来管理job。

List<Job> joblist=managementService.createJobQuery().processInstanceId("").list();




api到此算是看了个大概,后面该了解流程定义文件jPDL中的东西了,毕竟对一个流程都不清楚,
更谈不上操作流程了。






你可能感兴趣的:(jbpm)