JBPM4.4(2)-state结点和decision结点

简介: 做一个带有分支的流向流程 在执行seperate状态的时候分成了200和400两种情况 描述文件的内容如下: View Code 测试代码如下: View Code public class TestSperator extends JbpmTest...

做一个带有分支的流向流程

img_3b573ba83dfd68789eb02dfa6a86992f.png

在执行seperate状态的时候分成了200和400两种情况

描述文件的内容如下:

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
<? xml version="1.0" encoding="UTF-8" ?>

< process name ="fork" xmlns ="http://jbpm.org/4.4/jpdl" >
< start g ="237,28,48,48" name ="start1" >
< transition name ="to separate" to ="separate" g ="-71,-17" />
</ start >
< state g ="210,153,92,52" name ="separate" >
< transition name ="to 200" to ="200" g ="-41,-17" />
< transition name ="to 400" to ="400" g ="-41,-17" />
</ state >
< state g ="145,256,92,52" name ="200" >
< transition name ="to end1" to ="end1" g ="-47,-17" />
</ state >
< state g ="306,255,92,52" name ="400" >
< transition name ="to end1" to ="end1" g ="-47,-17" />
</ state >
< end g ="245,375,48,48" name ="end1" />
</ process >

测试代码如下:

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
public class TestSperator extends JbpmTestCase {

String deploymentId;

protected void setUp() throws Exception {
super .setUp();

deploymentId
= repositoryService.createDeployment()
.addResourceFromClasspath(
" com/jbpm/fork/fork.jpdl.xml " )
.deploy();
}

protected void tearDown() throws Exception {
repositoryService.deleteDeploymentCascade(deploymentId);

super .tearDown();
}

public void testSeparate() {
ProcessInstance processInstance
= executionService
.startProcessInstanceByKey(
" fork " );

System.out.println(
" 流程实例Id: " + processInstance.getId());
System.out.println(
" 流程定义Id: " + processInstance.getProcessDefinitionId());

ProcessInstance instance
= executionService.signalExecutionById(processInstance.getId());

// 判断当前是否位于state节点

System.out.println(
" 是否位于state节点: " + instance.isActive( " separate " ));
System.out.println(
" 向下执行... " );

ProcessInstance processInstance200
= executionService.signalExecutionById(processInstance.getId(), " to 200 " );

System.out.println(
" 当前流程是否位于200节点----> " + processInstance200.isActive( " 200 " ));
System.out.println(
" 当前流程是否结束----> " + processInstance200.isEnded());

ProcessInstance endinstance
= executionService.signalExecutionById(processInstance200.getId());

System.out.println(
" 当前流程是否结束----> " + endinstance.isEnded());


}
}

执行流程的结果如下:

img_f165a9857698ff692548957fadb55375.gif

使流程向下执行

executionService.signalExecutionById();

该方法有多个重载:

ProcessInstance signalExecutionById(String executionId);

//若在流程定义某一个节点没有分支时(只有一个transition时),调用此方法,可将流程继续向下执行 executionId为流程实例Id

ProcessInstance signalExecutionById(String executionId, String signalName);

//若在流程定义某一个节点有多个分支时(有多个transition时),调用此方法,可将流程沿着transition所指的方向向下执行

executionId为流程实例Id, signalName为流程定义中transition节点的name属性的值

ProcessInstance signalExecutionById(String executionId, String signalName, Map<String, ?> parameters);

用于将流程沿着signalName方向(transition的name属性所指的方向)向下继续执行,在执行的过程中顺便传递参数parameters

ProcessInstance signalExecutionById(String executionId, Map<String, ?> parameters);

用于将流程向下继续执行,在执行的过程中顺便传递参数parameters

注:当一个节点有多个分支时,若要通过signalExecutionById()方法将流程向下执行必须明确指出signalName即(transition的name属性所指的方向),否则流程不会向下执行,仍会停留在当前节点。因为jbpm不确定流程该流向那个方向。

接下来是一个decision的例子,这个是一个分支判断的节点,相当于我们程序中的switch case

下面画一个选择向左还是向右的例子

img_ad8fb47bbcb8362c72d50d8742b44005.gif

定义文件如下:

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
<? xml version="1.0" encoding="UTF-8" ?>

< process name ="decision" xmlns ="http://jbpm.org/4.4/jpdl" >
< start g ="246,30,48,48" name ="start1" >
< transition name ="to wait" to ="wait" g ="-47,-17" />
</ start >
< state g ="231,112,92,52" name ="wait" >
< transition name ="to exclusive1" to ="exclusive1" g ="-83,-17" />
</ state >
< decision g ="252,204,48,48" name ="exclusive1" >
< transition name ="to left" to ="left" g ="-47,-17" >
< condition expr ="${coder=='left'}" ></ condition >
</ transition >
< transition name ="to right" to ="right" g ="-53,-17" >
< condition expr ="${coder=='right'}" ></ condition >
</ transition >
</ decision >
< state g ="175,295,92,52" name ="left" >
< transition name ="to end1" to ="end1" g ="-47,-17" />
</ state >
< state g ="325,292,92,52" name ="right" >
< transition name ="to end1" to ="end1" g ="-47,-17" />
</ state >
< end g ="268,370,48,48" name ="end1" />
</ process >

其中有几种方式可以处理流程的走向

第一种,内置条件

即在流程定义中设置每一个transition的子节点condition,并为每一个condition填充expr属性

形如:

<condition expr="${coder=='left'}"></condition>

对应的测试流程如下,需要增加

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
Map < String, String > map = new HashMap < String, String > ();
// coder为流程定义中表达式的名称
map.put( " coder " , " left " );

ProcessInstance processInstance
= executionService.startProcessInstanceByKey( " decision " ,map);

如果map中order的值指定的有问题那么就会抛出异常

测试程序如下:

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
public class TestDecision extends JbpmTestCase {

String deploymentId;

protected void setUp() throws Exception {
super .setUp();

deploymentId
= repositoryService.createDeployment()
.addResourceFromClasspath(
" com/jbpm/decision/decision.jpdl.xml " )
.deploy();
}

protected void tearDown() throws Exception {
repositoryService.deleteDeploymentCascade(deploymentId);

super .tearDown();
}

public void testDescsion() {

Map
< String, String > map = new HashMap < String, String > ();
// coder为流程定义中表达式的名称
map.put( " coder " , " left " );

ProcessInstance processInstance
= executionService.startProcessInstanceByKey( " decision " ,map);

System.out.println(
" 流程实例Id: " + processInstance.getId());
System.out.println(
" 流程定义Id: " + processInstance.getProcessDefinitionId());

System.out.println(
" 是否位于state节点: " + processInstance.isActive( " wait " ));

ProcessInstance decisionInstance
= executionService.signalExecutionById(processInstance.getId());

// 判断当前是否位于wait节点
System.out.println( " 是否位于wait节点: " + decisionInstance.isActive( " wait " ));
System.out.println(
" 因为已经有值所以自动向下执行... " );
System.out.println(
" 是否位于left节点: " + decisionInstance.isActive( " left " ));

// 向下执行
ProcessInstance endinstance = executionService.signalExecutionById(decisionInstance.getId());

System.out.println(
" 当前流程是否结束----> " + endinstance.isEnded());

}
}

执行结果如图所示:

img_7093156a5186bd293ed8e1d913a41b10.gif

因为在开始的时候指定了流程处理的方向,所以流程向left方向自动执行。

第二种,更像switch case

在decision节点上指定

<decision g="252,204,48,48" name="exclusive1" expr="${toWhere}">

修改代码为:

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
Map < String, String > map = new HashMap < String, String > ();
// coder为流程定义中表达式的名称
map.put( " toWhere " , " to left " );

其它部分不变,可以看到结果和原来的相同。

第三种,配置handler子类

在流程定义中在decision节点内部配置<handler/>子节点,并设置该元素的class属性为你自己的类)该类实现了org.jbpm.api.jpdl.DecisionHandler.你需要重写

String decide(OpenExecution execution);方法即可,在该方法最终返回decision活动后的下一个transition的name属性的值。

修改配置文件

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
< decision g ="252,204,48,48" name ="exclusive1" >
< handler class ="com.jbpm.decision.HandlerDecision" ></ handler >
< transition name ="to left" to ="left" g ="-47,-17" >
</ transition >
< transition name ="to right" to ="right" g ="-53,-17" >
</ transition >
</ decision >

添加HandlerDecision并且实现DecisionHandler

代码如下:

 

img_1c53668bcee393edac0d7b3b3daff1ae.gif img_405b18b4b6584ae338e0f6ecaf736533.gif View Code
 
  
@SuppressWarnings( " serial " )
public class HandlerDecision implements DecisionHandler {

@Override
public String decide(OpenExecution execution) {
// TODO Auto-generated method stub
String toWhere = execution.getVariable( " toWhere " ).toString();
String result
= null ;

if ( " left " .equals(toWhere)) {
result
= " to left " ;
}
else if ( " right " .equals(toWhere)) {
result
= " to right " ;
}
return result;
}

}

测试代码只需将map中的值进行简单修改即可

 

 
 
Map < String, String > map = new HashMap < String, String > ();
// coder为流程定义中表达式的名称
map.put( " toWhere " , " left " );
执行测试,得到的流程和之前完全相同。


目录
相关文章
|
5天前
|
数据采集 人工智能 自然语言处理
3分钟采集134篇AI文章!深度解析如何通过云无影AgentBay实现25倍并发 + LlamaIndex智能推荐
结合阿里云无影 AgentBay 云端并发采集与 LlamaIndex 智能分析,3分钟高效抓取134篇 AI Agent 文章,实现 AI 推荐、智能问答与知识沉淀,打造从数据获取到价值提炼的完整闭环。
389 93
|
6天前
|
域名解析 人工智能
【实操攻略】手把手教学,免费领取.CN域名
即日起至2025年12月31日,购买万小智AI建站或云·企业官网,每单可免费领1个.CN域名首年!跟我了解领取攻略吧~
|
5天前
|
SQL 人工智能 自然语言处理
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
随着生成式AI的普及,Geo优化(Generative Engine Optimization)已成为企业获客的新战场。然而,缺乏标准化流程(Geo优化sop)导致优化效果参差不齐。本文将深入探讨Geo专家于磊老师提出的“人性化Geo”优化体系,并展示Geo优化sop标准化如何帮助企业实现获客效率提升46%的惊人效果,为企业在AI时代构建稳定的流量护城河。
391 156
Geo优化SOP标准化:于磊老师的“人性化Geo”体系如何助力企业获客提效46%
|
5天前
|
数据采集 缓存 数据可视化
Android 无侵入式数据采集:从手动埋点到字节码插桩的演进之路
本文深入探讨Android无侵入式埋点技术,通过AOP与字节码插桩(如ASM)实现数据采集自动化,彻底解耦业务代码与埋点逻辑。涵盖页面浏览、点击事件自动追踪及注解驱动的半自动化方案,提升数据质量与研发效率,助力团队迈向高效、稳定的智能化埋点体系。(238字)
272 158
|
13天前
|
机器人 API 调度
基于 DMS Dify+Notebook+Airflow 实现 Agent 的一站式开发
本文提出“DMS Dify + Notebook + Airflow”三位一体架构,解决 Dify 在代码执行与定时调度上的局限。通过 Notebook 扩展 Python 环境,Airflow实现任务调度,构建可扩展、可运维的企业级智能 Agent 系统,提升大模型应用的工程化能力。