jbpm学习笔记(六) jbpm的核心 jpdl流程定义语言详解(一)

jpdl是jbpm的最核心,涉及到各方面的内容,所以我打算用多篇博文记录它
一, Jpdl语言是以xml为表现形式的,根元素是process,我们看看process元素的一些属性
[table]
|属性|类型|默认值|是否必需|作用描述|
|Name|名称文本|无|必需|作为流程显示的标签|
|Key|字母,数字,下划线的组合|如果省略,key会根据name生成,name中非字母以及非数字的字符会被替换为下划线|可选|用来标示不同的流程定义。拥有同一个key的流程定义允许有不同的version。对于已发布的同一流程定义的各个版本来说,“key:name”组合必需是完全一样的|
|Version|整型|同一流程定义(即二者的”key:name”相同),后部署的会比先部署的version加1,如果是第一次部署,version从1开始|可选|标示同一流程定义的不同版本|

[/table]


二,下面介绍流程控制活动,这些活动有:
Start—开始活动
State—活动
Decision—判断活动
Fork—join----分支/聚合活动
End –结束活动
Task—人工任务活动
Sub-process—子流程活动
Custom—自定义活动

1,
Start活动的意义在于指明一个流程的实例应该从哪里开始发起,即流程的入口,在一个流程定义里必需拥有一个start活动。Start活动必须有一个流出转移(transition),这个转移会在流程通过start活动的时候执行。

2,
State 当需要使用业务流程受到某些特定的外部干预后再继续运行,而在这之前流程”陷入”一个中断等待的状态时,就需要这么一个state活动。当流程运行到state活动时,会自动陷入等待状态(waitting state),也就是说流程引擎在收到外部触发信号之前会一直使流程实例在此state活动等待。从这个方面来说:task活动可以说是一种特殊化的state活动。
State活动除了最基本的name属性和transition等元素外,没有独特的属性或元素。
相关jpdl如下:
<?xml version="1.0" encoding="UTF-8"?>

<process name="angel" xmlns="http://jbpm.org/4.4/jpdl">
<!-- 流程开始后转移到wait for response state -->
<start>
<transition to="wait for response" />
</start>

<!-- 这里有两个transition供选择,二者选其一 -->
<state name="wait for response">
<transition name="accept" to="submit document" />
<transition name="reject" to="try again" />
</state>

<!-- 此活动被上面名为accept 的transition指向 -->
<state name="submit document" />

<!-- 此活动被上面名为reject 的transition指向 -->
<state name="try again" />

</process>

下面我们编写代码使此流程运行起来,首先根据此流程定义发起实例:
 ProcessInstance    
processInstance=executionService.startProcessInstanceByKey(“StateChoice”);


假如现在流程到达了 wait for response state活动,则实例会一直等待外部触发的出现。此state活动拥有两个流出转移,外部触发调用通过提供不同的流出转移信号名称(signal name) 来实现选择流转,下面使用accept作为信号名称:
       //获取流程执行的ID
String executionId=processInstance.findActiveExecutionIn(“wait
for response”).getId();
//触发accept型号
processInstance=executionService.signalExecutionById
(executionId,”accept”);
assertTrue(processInstance.isActive(“submit document”));



3,decision
根据条件在多个流转路径中选择其一通过,也就是做一个决定性的判断,这时候使用
decision活动是个正确的选择。

Decision活动可以拥有多个流出转移,当流程实例到达decision活动时,会根据最先匹配成功的一个条件 自动地通过相应的流出转移。

(1),使用decision活动的condition
使用decision活动的condition元素
Decision活动中会运行并判断其每一个transition元素里的流转条件----流转条件由condition元素表示。当遇到一个transition的condition值为true或者一个没有设置condition的transition,那么流程就立刻流向这个transtion。
相关jpdl如下:
<?xml version="1.0" encoding="UTF-8"?>

<process name="decisionConditions" xmlns="http://jbpm.org/4.4/jpdl">
<start>
<transition to="decisionGo" />
</start>
<!-- "#{content}" 即为判断表达式。在这里会返回变量content的字符串值 -->
<decision name="decisionGo">

<!-- content 值为good时的转移 -->
<transition to="submit" >
<condition expr="#{content=='good'}"/>
</transition>

<!-- content 值为bad时的转移 -->
<transition to="try again" >
<condition expr="#{content=='bad'}"/>
</transition>
<!-- content 值为ugly时的转移 -->
<transition to="give up" >
<condition expr="#{content=='ugly'}"/>
</transition>

</decision>

<state name="submit" />
<state name="try again" />
<state name="give up" />

</process>


在单元测试中,设置流程变量content的值为good:
Map<String,Object> vals=new HashMap<String, Object> 
();
vals.put("content","good");

//发起流程实例
ProcessInstance
processInstance=executionService.startProcessInstanceByKey("decisionConditions",vals);

//那么,可以断言流程实例流向了submit活动
assertTrue(processInstance.isActive("submit"));


(2),使用decision活动的expr属性
你可以利用decision活动本身具有的expr(表达式)属性来判断流程的转向,decision活动的expr属性值可直接返回字符串类型的流出转移名称,指定需要流转的路径。
相关jpdl代码如下
<?xml version="1.0" encoding="UTF-8"?>

<process name="decisionExpr" xmlns="http://jbpm.org/4.4/jpdl">
<start>
<transition to="decisionGo" />
</start>
<!-- "#{content}" 即为判断表达式。在这里会返回变量content的字符串值 -->
<decision expr="#{content}" name="decisionGo">

<!-- content 值为good时的转移 -->
<transition name="good" to="submit" />

<!-- content 值为bad时的转移 -->
<transition name="bad" to="try again" />

<!-- content 值为ugly时的转移 -->
<transition name="ugly" to="give up" />

</decision>

<state name="submit" />
<state name="try again" />
<state name="give up" />

</process>

在单元测试中,设置流程变量content的值为good:
Map<String,Object> vals=new HashMap<String, Object>();
vals.put("content","good");

//发起流程实例
ProcessInstance processInstance=executionService.startProcessInstanceByKey("decisionExpr",vals);

/那么,可以断言流程实例流向了submit活动
assertTrue(processInstance.isActive("submit"));

(3),使用decision活动的handler元素
也许以上两种判断流转的方式对你来说还不够灵活,也许你需要在判断流转时计算大量,复杂的业务逻辑,那么,自己实现判断处理接口,即通过decision handler的方式,将给你无限自由的空间。
首先,必须实现DecisionHandler接口,将流转判断的决定权委派给这个实现类,这个接口的定义如下:

Public interface DecisionHandler{
//这个接口就只有一个方法,提供流程实例的执行上下文(execution)作为参数,需要返回字符串型的转移名称
String decide(OpenExecution execution);

}
这个handler需要作为decision活动的子元素被配置。
相关的jpdl如下:
<?xml version="1.0" encoding="UTF-8"?>

<process name="decisionTest" xmlns="http://jbpm.org/4.4/jpdl">
<start>
<transition to="decisionGoHandler" />
</start>

<decision name="decisionGoHandler">
<!-- 所有的流转判断逻辑都被委派给了这个ContentEvaluation handler 统一处理 -->
<handler class="org.test.ContentEvaluation" />
<transition name="good" to="submit"/>
<transition name="bad" to="try again"/>
<transition name="ugly" to="give up"/>
</decision>

<state name="submit" />
<state name="try again" />
<state name="give up" />

</process>
ContentEvaluation这个类的代码如下:


package org.test;
import org.jbpm.api.jpdl.DecisionHandler;
import org.jbpm.api.model.OpenExecution;

public class ContentEvaluation implements DecisionHandler {

@Override
public String decide(OpenExecution execution) {
String content = (String) execution.getVariable("content");
if (content.equals("you are good")) {
return "good";
}
if (content.equals("you are bad")) {
return "bad";
}
return "ugly";
}

}
运行流程实例的单元测试代码如下:
Map<String,Object> vals=new HashMap<String, Object>();

//设置流程变量content的值为 you are good
vals.put("content","you are good");

//发起流程实例,并设置流程变量
ProcessInstance pi=executionService.startProcessInstanceByKey("decisionHandler",vals);

//断言流向了预期的活动
assertTrue(pi.isActive("submit"));


现在有一个问题出现了,发觉了吗,decision活动和state活动都能实现条件流转,是的,但是这两种方式有何区别,在实际业务应用中该选择何种方式呢?
区别如下:
如果decision活动定义的流转条件没有任何一个得到满足,那么流程实例将无法进行下去,会抛出异常。
如果state活动有多个流出转移,且同样没有任何一个得到满足,那么流程实例将流向state活动定义的第一条流出转移,从而进行下去。
也就是说:decision活动具有更加严格的条件判断特性。
下篇讲解fork-join(分支/聚合活动)和end
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值