jbpm4.4 定义

jbpm 4.4 中一些概念


1, 流程定义(ProcessDefinition): 对整个流程步骤的描述., 相当于我们在编程过程过程用到的类, 是个抽象的概念.


2. 流程实例(ProcessInstance): 代表着流程定义的特殊执行例子, 相当于我们常见的对象. 他是类的特殊化.

最典型的属性就是跟踪当前节点的指针.


3. 流程引擎(ProcessEngine): 服务接口可以从 ProcessEngine 中获得, 它是从 Configuration 构建的, 如下:

ProcessEngine processEngine = new Configuration()
      .buildProcessEngine();

从流程引擎中可以获得如下的服务:

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


4. 部署流程(Deploying a process):

RepositoryService 包含了用来管理发布资源的所有方法,

如下可以发布流程定义.

String deploymentid = repositoryService.createDeployment()

    .addResourceFromClasspath("*.jpdl.xml")

    .deploy();

这个id 的格式是(key)-{version}.


5. 删除流程定义:

repositoryService.deleteDeployment(deploymentId); 可以用级联的方式, 也可以remove

 

6. 启动一个新的流程实例:

ProcessInstance processInstance = executionService.startProcessInstanceByKey("key");

如果启动指定版本的流程定义 , 用下面的方法 :

ProcessInstance processInstance =executionService.startProcessInstanceById("ID");

 

7. 使用变量

当一个新的流程实例启动时就会提供一组对象参数。 将这些参数放在variables 变量里, 然后可以在流程实例创建和启动时使用。

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 processInstance =

    executionService.startProcessInstanceByKey("ICL", variables);


8. 执行等待的流向:

当使用一个 state 活动时,执行(或流程实例) 会在到达state 的时候进行等待,

直到一个signal (也叫外部触发器)出现。 signalExecution 方法可以被用作这种情况。

执行通过一个执行id (字符串)来引用。

executionService.signalExecutionById(executionId);


9.TaskService 任务服务:

TaskService 的主要目的是提供对任务列表的访问途径。 例子代码会展示出如何为id 为 johndoe 

用户获得任务列表:

List<Task> taskList = taskService.findPersonalTasks("johndoe");

 

 

JBPM4 –ProcessEngine

在jBPM 内部通过各种服务相互作用。 服务接口可以从ProcessEngine 中获得, 它是从Configuration 构建的。

获得ProcessEngine : processEngine =Configuration.getProcessEngine ();


JBPM4 – RepositoryService

RepositoryService 包含了用来管理发布资源的所有方法。

部署流程

String deploymentid = repositoryService.createDeployment()  
    .addResourceFromClasspath("org/jbpm/examples/services/Order.jpdl.xml")  
    .deploy(); 

ZipInputStream zis = new ZipInputStream( this .getClass()

              .getResourceAsStream( "/com/jbpm/source/leave.zip" ));

// 发起流程,仅仅就是预定义任务,即在系统中创建一个流程,这是全局的,与具体的登陆 用户无关。然后,在启动流程时,才与登陆用户关联起来

String did = repositoryService .createDeployment()

              .addResourcesFromZipInputStream(zis).deploy(); 
通过上面的 addResourceFromClass 方法,流程定义 XML 的内容可以从文件,网址,字符串,输入流或 zip 输入流中获得。

每次部署都包含了一系列资源。每个资源的内容都是一个字节数组。 jPDL 流程文件都是以 .jpdl.xml 作为扩展名的。其他资源是任务表单和 java 类。

部署时要用到一系列资源,默认会获得多种流程定义和其他的归档类型。 jPDL 发布器会自动识别后缀名是 .jpdl.xml 的流程文件。

在部署过程中,会把一个 id 分配给流程定义。这个 id 的格式为 {key}-{version}  key  version 之间使用连字符连接。

如果没有提供 key (指在流程定义文件中,对流程的定义),会在名字的基础自动生成。生成的 key 会把所有不是字母和数字的字符替换成下划线。

同一个名称只能关联到一个 key ,反之亦然。

如果没有为流程文件提供版本号, jBPM 会自动为它分配一个版本号。请特别注意那些已经部署了的名字相同的流程文件的版本号。它会比已经部署的同一个 key 的流程定义里最大的版本号还大。没有部署相同 key 的流程定义的版本号会分配为 1 

删除流程定义

删除一个流程定义会把它从数据库中删除。

repositoryService.deleteDeployment(deploymentId); 

如果在发布中的流程定义还存在活动的流程实例,这个方法就会抛出异常。

如果希望级联删除一个发布中流程定义的所有流程实例,可以使用 deleteDeploymentCascade 

JBPM4 – TaskService

TaskService 的主要目的是提供对任务列表的访问途径。 例子代码会展示出如何为 id  johndoe 的用户获得任务列表

List<Task> taskList = taskService.findPersonalTasks("johndoe"); 

一般来说,任务会对应一个表单,然后显示在一些用户接口中。 表单需要可以读写与任务相关的数据。

// read task variables  
Set<String> variableNames = taskService.getVariableNames(taskId);  
variables = taskService.getVariables(taskId, variableNames); 

// write task variables  
variables = new HashMap<String, Object>();  
variables.put("category", "small");  
variables.put("lires", 923874893);  
taskService.setVariables(taskId, variables); 


taskSerice
 也用来完成任务。 
taskService.completeTask(taskId);  
taskService.completeTask(taskId, variables);  
taskService.completeTask(taskId, outcome);  
taskService.completeTask(taskId, outcome, variables); 

这些 API 允许提供一个变量 map ,它在任务完成之前作为流程变量添加到流程里。 它也可能提供一个  外出 outcome” ,这会用来决定哪个外出转移会被选中。 逻辑如下所示:

如果一个任务拥有一个没用名称的外向转移: 
taskService.getOutcomes() 返回包含一个 null 值集合,。 
taskService.completeTask(taskId) 
会使用这个外向转移。 
taskService.completeTask(taskId, null) 
会使用这个外向转移。 
taskService.completeTask(taskId, "anyvalue") 
会抛出一个异常。

如果一个任务拥有一个有名字的外向转移: 
taskService.getOutcomes() 返回包含这个转移名称的集合。 
taskService.completeTask(taskId) 
会使用这个单独的外向转移。 
taskService.completeTask(taskId, null) 
会抛出一个异常(因为这里没有无名称的转移)。 
taskService.completeTask(taskId, "anyvalue") 
会抛出一个异常。 
taskService.completeTask(taskId, "myName") 
会根据给定的名称使用转移。

如果一个任务拥有多个外向转移,其中一个转移没有名称,其他转移都有名称: 
taskService.getOutcomes() 返回包含一个 null 值和其他转移名称的集合。 
taskService.completeTask(taskId) 
会使用没有名字的转移。 
taskService.completeTask(taskId, null) 
会使用没有名字的转移。 
taskService.completeTask(taskId, "anyvalue") 
会抛出异常。 
taskService.completeTask(taskId, "myName") 
会使用名字为 'myName' 的转移。

如果一个任务拥有多个外向转移,每个转移都拥有唯一的名字: 
taskService.getOutcomes() 返回包含所有转移名称的集合。 
taskService.completeTask(taskId) 
会抛出异常,因为这里没有无名称的转移。 
taskService.completeTask(taskId, null) 
会抛出异常,因为这里没有无名称的转移。 
taskService.completeTask(taskId, "anyvalue") 
会抛出异常。 
taskService.completeTask(taskId, "myName") 
会使用名字为 'myName' 的转移。

任务可以拥有一批候选人。候选人可以是用户也可以是用户组。用户可以接收自己是候选人的任务。接收任务的意思是用户会被设置为被分配给任务的人。在那之后,其他用户就不能接收这个任务了。

人们不应该在任务做工作,除非他们被分配到这个任务上。用户界面应该显示表单,如果他们被分配到这个任务上,就允许用户完成任务。对于有了候选人,但是还没有分配的任务,唯一应该暴露的操作就是  接收任务  

 

JBPM4 – ExecutionService

最新的流程实例 -- ByKey 
下面是为流程定义启动一个新的流程实例的最简单也是 最常用的方法:

ProcessInstance processInstance = executionService.startProcessInstanceByKey ("ICL");

上面 service 的方法会去查找 key  ICL 的最新版本的流程定义, 然后在最新的流程定义里启动流程实例。

 key  ICL 的流程部署了一个新版本, startProcessInstanceByKey 方法会自动切换到最新部署的版本。

原来已经启动的流程,还是按照启动时刻的版本执行。


指定流程版本 -- ById 
换句话说,你如果想根据特定的版本启动流程实例, 便可以使用流程定义的 id 启动流程实例。如下所示:

ProcessInstance processInstance = executionService.startProcessInstanceById ("ICL-1");


使用 key

我们可以为新启动的流程实例分配一个 key( 注意: 这个 key 不是 process  key ,而是启动的 instance  key ) ,这个 key 是用户执行的时候定义的,有时它会作为  业务 key” 引用。一个业务 key 必须在流程定义的所有版本范围内是唯一的。通常很容易在业务流程领域找到这种 key 。比如,一个订单 id 或者一个保险单号。 
ProcessInstance processInstance = executionService.startProcessInstanceByKey ("ICL", "CL92837");

// 2 个参数: 
//  
第一个参数 processkey ,通过这个 key 启动 process 的一个实例 
//  
第二个参数为这里所说的实例 key(instance key)

key 可以用来创建流程实例的 id ,格式为 {process-key}.{execution-id} 。所以上面的代码会创建一个 id  ICL.CL92837 的流向( execution )。

如果没有提供用户定义的 key ,数据库就会把主键作为 key  这样可以使用如下方式获得 id  
ProcessInstance processInstance = executionService.startProcessInstanceByKey ("ICL"); 
String pid = processInstance.getId();

最好使用一个用户定义的 key  特别在你的应用代码中,找到这样的 key 并不困难。提供给一个用户定义的 key ,你可以组合流向的 id ,而不是执行一个基于流程变量的搜索 那种方式太消耗资源了。

使用变量

当一个新的流程实例启动时就会提供一组对象参数。 将这些参数放在 variables 变量里, 然后可以在流程实例创建和启动时使用。 
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 processInstance = executionService.startProcessInstanceByKey ("ICL", variables);

启动 instance

启动 instance ,必须要知道 processdefinition 的信息: processdefinition 可以通过 2 种方式获取: 
ByKey
 :通过 ProcessKey ,启动该 Process 的最新版本 
ById
    通过 Process  ID ,启动该 Process 的特定的版本

其他的参数,其余还可以在启动 Instance 的时候,给流程 2 个参数: 
InstanceKey
 :这个 instanceKey 必须在整个流程定义的所有范围版本中唯一,如果用户不给于提供,系统也会自己生成; 
一个 Map<String, ?> 表:启动流程时候给予的变量信息

执行等待的流向

当使用一个 state 活动时,执行(或流程实例)会在到达 state 的时候进行等待,直到一个 signal (也叫外部触发器)出现。 signalExecution 方法可以被用作这种情况。执行通过一个执行 id (字符串)来引用。

在一些情况下,到达 state 的执行会是流程实例本身。但是这不是一直会出现的情况。在定时器和同步的情况,流程是执行树形的根节点。所以我们必须确认你的 signal作用在正确的流程路径上。

获得正确的执行的比较好的方法是给 state 活动分配一个事件监听器,像这样: 
<state name="wait">  
  <on event="start">  
    <event-listener class="org.jbpm.examples.StartExternalWork" />  
  </on>  
  ...  
</state> 

在事件监听器 StartExternalWork 中,你可以执行那些需要额外完成的部分。在这个事件监听器里,你也可以通过 execution.getId() 获得确切的流程 id 。那个流程id ,在额外的工作完成后,你会需要它来提供给 signal 操作的:

executionService.signalExecutionById (executionId); 

这里有一个可选的(不是太推荐的)方式,来获得流程 id ,当流程到达 state 活动的时候。只可能通过这种方式获得执行 id ,如果你知道哪个 JBPM API 调用了之后,流程会进入 state 活动:

// assume that we know that after the next call  
// the process instance will arrive in state external work  
ProcessInstance processInstance = executionService.startProcessInstanceById(processDefinitionId); 

// or ProcessInstance processInstance =  
//  executionService.signalProcessInstanceById(executionId);  
Execution execution = processInstance.findActiveExecutionIn("external work");  
String executionId = execution.getId(); 

 

JBPM4 – HistoryService

在流程实例执行的过程中,会不断触发事件。从那些事件中,运行和完成流程的历史信息会被收集到历史表中。

HistoryService 提供了 对那些信息的访问功能。

如果想查找某一特定流程定义的所有流程实例, 可以像这样操作:

List<HistoryProcessInstance> historyProcessInstances = historyService  
  .createHistoryProcessInstanceQuery()  
  .processDefinitionId("ICL-1")  
  .orderAsc(HistoryProcessInstanceQuery.PROPERTY_STARTTIME)  
  .list(); 

单独的活动流程也可以作为 HistoryActivityInstance 保存到历史信息中。

List<HistoryActivityInstance> histActInsts = historyService  
    .createHistoryActivityInstanceQuery()  
    .processDefinitionId("ICL-1")  
    .activityName("a")  
    .list(); 

也可以使用简易方法 avgDurationPerActivity  choiceDistribution 。可以通过 javadocs 获得这些方法的更多信息。

有时,我们需要获得指定流程实例已经过的节点的完整列表。下面的查询语句可以用来获得所有已经执行的节点列表:

List<HistoryActivityInstance> histActInsts = historyService  
    .createHistoryActivityInstanceQuery()  
    .processInstanceId("ICL.12345")  
    .list(); 

上面的查询与通过 execution id 查询有一些不同。有时 execution id 和流程实例 id 是不同的, 当一个节点中使用了定时器, execution id 中就会使用额外的后缀, 这就会导致当我们通过 execution id 查询时, 这个节点不会出现在结果列表中。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值