`
man1900
  • 浏览: 432835 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

JBPM4的子流程与父流程的设计及开发

阅读更多

     【JBPM4的子流程与父流程的设计及开发】

 

 

         子流程与父流程的支持一般都要解决子流程的定义、父流程与子流程的关系定义。在 Jbpm4 中,子流程其也认为是一种独立的流程,这样的话,所以子流程与父流程的定义就不存在问题,但他们的关系如何休现, jbpm4的流程定义是通过xml文件来设定的,所以没有所谓的数据库外键关系,它却是在流程定义中,通过一个 <sub-process key=” 子流程的 key”/>节点来体现父与子流程之间的关系的。

 JBPM4 的对子流程的支持也已经很完善了,但用起来感觉还不够方便,主要面临以下几个问题:

1.  子流程完成后,如何跳回主流程
2.  子流程的人员如何指派
3.   子流程与父流程如何传递数据


我们以下面两个流程为示例,其中仓库检验订单子流程也是这个父流程的一个节点,我们在流程设计器上则通过绑定其 key ,如 :

jbpm4 父流程设置子流程节点则需要设置Key,其子流程的定义如:



        jbpm 在启动父流程运行后,当跳至下一步为子流程,其就会自动启动子流程,这个动作,在我们的 jbpmserviceimpl 类中有,完成当前任务并且跳至下一步时,我们会取到下一任务的执行人员,并且进行了授权。但当完成子流程时,需要跳至父流程,流程引擎则需要知道其跳转的 路径。

       JBPM4 提供了三种方式来进行返回至父流程:
方法一(我们称之为输入活动节点)
父流程示意图:


其子流程示意图如:

对应的流程定义XML文件:

子流程:

<?xml version="1.0" encoding="UTF-8"?>
<process name="SubProcessReview" xmlns="http://jbpm.org/4.4/jpdl">

  <start g="25,101,48,48">
    <transition to="get approval"/>
  </start>

  <task name="get approval"
        assignee="johndoe"
        g="107,97,127,52">

    <transition name="ok" to="ok" g="171,71:9,-16"/>
    <transition name="nok" to="nok" g="-16,-16"/>
    <transition name="reject" to="reject" g="170,179:8,3"/>
  </task>

  <end name="ok" g="269,48,88,52" />
  <end name="nok" g="270,101,88,52" />
  <end name="reject" g="270,156,88,52"/>
</process>

 


   父流程:

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

<process name="SubProcessDocument" xmlns="http://jbpm.org/4.4/jpdl">

  <start g="43,109,48,48">
    <transition to="review" />
  </start>

  <sub-process name="review"
               sub-process-key="SubProcessReview"
               g="118,106,99,52">

    <transition name="ok" to="next step" g="167,67:6,-19"/>
    <transition name="nok" to="update" g="-22,-18"/>
    <transition name="reject" to="close" g="167,200:7,3"/>
  </sub-process>

  <state name="next step" g="255,41,88,52"/>
  <state name="update" g="256,106,88,52"/>
  <state name="close" g="258,175,88,52"/>

</process>

 


我们发现子流程的跳至结束的 transition 名则为父流程中的子流程节点的跳出分支路径,这样,完成子流程任务的调用则为如下方式:

taskService.completeTask(task.getId(), "ok");

 

说明:这种方法要求我们的子流程跳出分支与外面的父流程中的子流程任务的跳出分支一致。

方法二(我们称之为输出对象)

子流程则如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<process name="SubProcessReview" xmlns="http://jbpm.org/4.4/jpdl">
  <start g="20,20,48,48">
    <transition to="get approval"/>
  </start>
  <task name="get approval"
        assignee="johndoe"
        g="96,16,127,52">

    <transition to="end"/>
  </task>

  <end name="end" g="254,19,88,52" />

</process>

 

   父流程定义:

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

<process name="SubProcessDocument" xmlns="http://jbpm.org/4.4/jpdl">

  <start g="36,109,48,48">
    <transition to="review" />
  </start>

  <sub-process name="review"
               sub-process-key="SubProcessReview"
               outcome="#{result}"
               g="118,106,99,52">

    <transition name="ok" to="next step" g="167,67:6,-19">
      <outcome-value>
        <int value="100"/>
      </outcome-value>
    </transition>
    <transition name="nok" to="update" g="-22,-18">
      <outcome-value>
        <int value="200"/>
      </outcome-value>
    </transition>
    <transition name="reject" to="close" g="167,200:7,3">
      <outcome-value>
        <int value="300"/>
      </outcome-value>
    </transition>
  </sub-process>

  <state name="next step" g="255,41,88,52"/>
  <state name="update" g="256,106,88,52"/>
  <state name="close" g="258,175,88,52"/>

</process>

 

其完成子流程任务调用方式:

// the result variable is set in the task
    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("result", 100);
    taskService.setVariables(task.getId(), variables);

    // the task in the sub process instance is completed
taskService.completeTask(task.getId());

 

说明:这里则告诉我们,在完成子任务的时候,则是通过在子任务中完成的时候,加上结果的变量,父流程则在定义中通过结果的变量,以决定其跳至下一哪个节点。
这种方案则要求我们父流程定义需要进行变量参数判定,并且在子流程中加上变量参数值,以通过该方式来进行跳转。


方法三:我们称之为 ( 输出值 )

与方法二有点不尽相同,其父流程中的子流程那里的跳转没有加参数,其父定义如下:

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

<process name="SubProcessDocument" xmlns="http://jbpm.org/4.4/jpdl">

  <start g="36,109,48,48">
    <transition to="review" />
  </start>

  <sub-process name="review"
               sub-process-key="SubProcessReview"
               outcome="#{result}"
               g="118,106,99,52">

    <transition name="ok" to="next step" g="167,67:6,-19"/>
    <transition name="nok" to="update" g="-22,-18"/>
    <transition name="reject" to="close" g="167,200:7,3"/>
  </sub-process>

  <state name="next step" g="255,41,88,52"/>
  <state name="update" g="256,106,88,52"/>
  <state name="close" g="258,175,88,52"/>

</process>

 

其子流程任务的完成调用如下:

// the result variable is set in the task
    Map<String, Object> variables = new HashMap<String, Object>();
    variables.put("result", "ok");
    taskService.setVariables(task.getId(), variables);
   
    // the task in the sub process instance is completed
    taskService.completeTask(task.getId());

 

说明:这里调用返回的变量值则为父流程中了子流程节点的跳出分支。父流程的定义也相对简单了,假若我们子流程的跳出至父流程的分支由用户自己来选择的话,则方法三 是一种非常理想的做法。相对方法一来说,其又不需要在子流程的结束分支需要搞得跟父流程的子流程节点跳出分支一样。若需要在子流程表单中,根据业务表单的 计算情况,自动跳到父流程的相应节点上,则可以选择方法二。

 

在 J.Office2 中,我们则选择第三种方法,让用户自己选择跳转分支路径。我们把在子流程中的最后一步,准备跳到结束节点时,让用户自己去选择在父流程中分支跳转路径,并 且把用户选择的路径保存至流程变量中,流程引擎则自己帮我们实现跳转功能,因此,一切问题都迎刃而解。
下面我们来看一下,如何解决在子流程取到其在父流程中的跳转分支路径,我们通过子流程的任务 id 来获取,方法示例如:

/**
      * 通过子流程的任务实例id,取得子流程在父流程的跳转分支
      * @param subFlowTaskId  子流程的任务id
      * @return
      */
     public List<Transition> getTransitionsBySubFlowTaskId(String subFlowTaskId){
         TaskImpl taskImpl = (TaskImpl) taskService.getTask(subFlowTaskId);
         if(taskImpl.getExecution().getSuperProcessExecution()!=null){
             ExecutionImpl parentPi=taskImpl.getExecution().getSuperProcessExecution();
             EnvironmentFactory environmentFactory = (EnvironmentFactory) processEngine;
                EnvironmentImpl env = environmentFactory.openEnvironment();
                try {
                    if (parentPi.getActivity() != null) {
                        List outTrans=parentPi.getActivity().getOutgoingTransitions();
                        return outTrans;
                    }
                } finally {
                    env.close();
                }
         }
         return new ArrayList();
     }

 
当我们在执行子流程时,我们看到如下的示意图:

 

在子流程中的任务表单中,则可以选择跳回父流程的分支。

 

 


那么子流程与父流程中的是如何传递参数?

       其还是采用流程变量方式,也则是在子流程变量中设置的流程变量,在父流程还是可以取到,只不过是需要设置输出至父流程。

如子流程定义为:

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

<process name="SubProcessDocument" xmlns="http://jbpm.org/4.4/jpdl">

  <start g="20,20,48,48">
    <transition to="review" />
  </start>

  <sub-process name="review"
               sub-process-key="SubProcessReview"
               g="96,16,127,52">

    <parameter-in var="document" subvar="document" />
    <parameter-out var="reviewResult" subvar="result" />

    <transition to="wait" />
  </sub-process>

  <state name="wait" g="255,16,88,52"/>

</process>

 

在子流程设置变量为名为 result ,其父流程则通过取名为 reviewResult 可以取到对应值。

 

调用如:

 

 String result = (String) executionService.getVariable(processInstance.getId(), "reviewResult");

 

整个实现效果演示可以参考:

http://www.jee-soft.cn/demoDetail.htm?demoId=5&decorator=blank


  • 大小: 70.1 KB
  • 大小: 47 KB
  • 大小: 35.8 KB
  • 大小: 32.1 KB
  • 大小: 21.9 KB
  • 大小: 52.5 KB
  • 大小: 60.5 KB
分享到:
评论
1 楼 电竞杀神张无忌 2017-03-14  
这是主流程调用子流程报的错大神指导原因吗?
             信息: exception while executing command org.jbpm.pvm.internal.cmd.CompleteTaskCmd@78cf7825
javax.el.PropertyNotFoundException: Cannot resolve identifier 'taskb22b3d67407b47489d1540a9b3d0782b'
at de.odysseus.el.tree.impl.ast.AstIdentifier.eval(AstIdentifier.java:86)
at de.odysseus.el.tree.impl.ast.AstEval.eval(AstEval.java:51)
at de.odysseus.el.tree.impl.ast.AstNode.getValue(AstNode.java:28)
at de.odysseus.el.TreeValueExpression.getValue(TreeValueExpression.java:122)
at org.jbpm.pvm.internal.el.UelValueExpression.evaluateInScope(UelValueExpression.java:52)
at org.jbpm.pvm.internal.el.Expression.evaluate(Expression.java:112)
at org.jbpm.pvm.internal.model.ExecutionImpl.initializeAssignments(ExecutionImpl.java:778)
at org.jbpm.jpdl.internal.activity.TaskActivity.execute(TaskActivity.java:107)
at org.jbpm.jpdl.internal.activity.TaskActivity.execute(TaskActivity.java:58)
at org.jbpm.pvm.internal.model.op.ExecuteActivity.perform(ExecuteActivity.java:60)
at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:672)
at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperation(ExecutionImpl.java:632)
at org.jbpm.pvm.internal.model.ExecutionImpl.start(ExecutionImpl.java:217)
at org.jbpm.jpdl.internal.activity.SubProcessActivity.execute(SubProcessActivity.java:114)
at org.jbpm.pvm.internal.model.op.ExecuteActivity.perform(ExecuteActivity.java:60)
at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperationSync(ExecutionImpl.java:672)
at org.jbpm.pvm.internal.model.ExecutionImpl.performAtomicOperation(ExecutionImpl.java:632)
at org.jbpm.pvm.internal.model.ExecutionImpl.signal(ExecutionImpl.java:430)
at org.jbpm.pvm.internal.model.ExecutionImpl.signal(ExecutionImpl.java:416)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:197)
at org.jbpm.pvm.internal.model.ExecutionImpl_$$_javassist_9.signal(ExecutionImpl_$$_javassist_9.java)
at org.jbpm.pvm.internal.task.TaskImpl.complete(TaskImpl.java:201)
at org.jbpm.pvm.internal.cmd.CompleteTaskCmd.execute(CompleteTaskCmd.java:65)
at org.jbpm.pvm.internal.cmd.CompleteTaskCmd.execute(CompleteTaskCmd.java:32)
at org.jbpm.pvm.internal.svc.DefaultCommandService.execute(DefaultCommandService.java:42)
at org.jbpm.pvm.internal.tx.StandardTransactionInterceptor.execute(StandardTransactionInterceptor.java:50)
at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.executeInNewEnvironment(EnvironmentInterceptor.java:53)
at org.jbpm.pvm.internal.svc.EnvironmentInterceptor.execute(EnvironmentInterceptor.java:40)
at org.jbpm.pvm.internal.svc.RetryInterceptor.execute(RetryInterceptor.java:56)
at org.jbpm.pvm.internal.svc.SkipInterceptor.execute(SkipInterceptor.java:43)
at org.jbpm.pvm.internal.svc.TaskServiceImpl.completeTask(TaskServiceImpl.java:96)
at com.bjhxqh.module.workflow.web.jbpm.jbpmutil.JbpmUtil.executeall(JbpmUtil.java:322)
at com.bjhxqh.module.workflow.web.jbpm.sp.WorkFlowEntry.onSave(WorkFlowEntry.java:252)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at com.bjhxqh.mvc.AbstractBasePage$AjaxRequest.ajaxProcess(AbstractBasePage.java:118)
at com.bjhxqh.mvc.component.base.ajaxrequest.AjaxRequestUtils.doAjaxRequest(AjaxRequestUtils.java:87)
at org.apache.jsp.$resource.com_bjhxqh_mvc_component_base_ajaxrequest.jsp.ajax_005frequest_jsp._jspService(ajax_005frequest_jsp.java:114)
at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)

相关推荐

    extjs jbpm4流程设计器

    6. **调试与执行**:集成jBPM4的执行环境,允许用户在设计环境中直接启动和调试流程实例。 7. **集成API**:与后端服务交互,实现流程实例的创建、查询、终止等操作。 8. **权限管理**:对流程设计的访问和修改...

    JBPM4 开发文档 实例 流程

    总结,JBPM4提供了一套完整的工作流管理系统,包括流程设计、执行、监控和优化等功能,通过JPdl语言和Hibernate整合,实现了流程的可视化和灵活管理。对于开发人员来说,理解这些核心概念和数据库表结构,能更好地...

    jbpm4整合流程例子 web流程设计器

    在这个例子中,我们将会探讨如何将jbpm4与Web流程设计器整合,以便更直观地设计和管理业务流程。 ### 1. jbpm4简介 jbpm4是基于Java的,遵循JBoss社区的开放源代码开发模式。它提供了一个灵活的、可扩展的框架,...

    JBPM4介绍开发步骤简介

    ### JBPM4开发步骤详解与服务接口功能解析 JBPM4是JBPM系列的一个版本,专注于提供一个轻量级的工作流引擎,适用于企业级应用的流程自动化。它以简单直观的方式设计,使得开发者能够轻松地定义、部署和执行业务流程...

    揭秘jbpm流程引擎内核设计思想及构架.doc

    "揭秘jbpm流程引擎内核设计思想及构架" jbpm流程引擎内核是指流程引擎中最基本的对象和服务,以及用于解决流程运行问题的调度机制和执行机制。它是流程引擎的灵魂,掌握了流程引擎内核的设计思想和结构,才能真正...

    jBPM4工作流应用开发指南.pdf

    - **开发指南:** 该指南是为开发者提供的一份实用手册,涵盖了从安装配置、环境搭建、流程设计、编码实践到调试优化等jBPM4工作流应用开发的各个方面。 ### 描述知识点: - **胡奇:** 虽然对于胡奇的具体身份未...

    jbpm流程设计器

    4. **集成开发环境**:jbpm流程设计器可以与Eclipse等IDE集成,提供更丰富的开发辅助功能,如代码提示、自动完成、版本控制等,提高开发效率。 5. **元数据支持**:它允许用户为流程中的各个元素添加元数据,如任务...

    JBoss JBPM4请假流程示例

    在JBoss JBPM4中,我们可以使用jbpm-designer工具来设计流程图,然后将其导出为XML格式的.bpel文件。 2. **请假申请任务**:流程开始时,员工提交请假申请,这对应于一个任务节点。任务数据可能包括请假人、请假...

    jbpm4jbpm5

    jbpm4jbpm5是关于jbpm流程管理框架的专题,涵盖了jbpm4和jbpm5两个主要版本。jbpm是一个开源的工作流管理系统,用于帮助开发者实现业务流程自动化。以下是基于给定文件的信息,深入解析jbpm4和jbpm5的知识点: 1. *...

    JBPM实践之:并发子流程的实现.doc

    JBPM(Java Business Process Management)是一个开源的工作流和业务流程管理系统,它允许开发者设计、执行、管理和监控业务流程。在JBPM中,处理并发子流程是实现复杂业务逻辑的重要一环。本文将深入探讨如何使用...

    JBPM4.4完整可用审批流程

    在实际应用中,开发者需要了解JBPM4的工作原理,包括流程实例、任务实例、信号和事件的概念,以及如何通过API或服务任务与外部系统交互。熟悉Maven的使用也是至关重要的,包括理解POM文件的结构、如何添加和排除依赖...

    JBPM5流程图设计规则

    JBPM5是一款强大的工作流管理系统,它基于BPMN2.0标准,用于设计和实现复杂的业务流程。BPMN2.0是一种业务流程建模符号语言,它为业务分析师和开发人员提供了一种标准化的方式来描述和交流业务流程。在JBPM5中,设计...

    JBPM流程引擎设计 工作流资料

    JBPM流程引擎设计是IT领域中的一个重要知识点,尤其对于那些希望理解和实施企业级工作流管理系统的人员来说,它是不可或缺的。 1. **流程建模**:JBPM支持BPMN 2.0(Business Process Model and Notation)标准,这...

    JBPM Web流程设计器

    【JBPM Web流程设计器】是一种基于Web的工具,它允许用户设计、管理和执行业务流程,类似于Eclipse中的jbpm插件。这个设计器采用JavaScript(js)和ExtJS库来构建,提供了一个直观的图形化界面,使得非技术人员也能...

    JBPM流程引擎资料

    文档《JBPM流程引擎资料》详细介绍了如何利用JBPM开发流程应用,涵盖了从框架构造到节点处理的方方面面。 首先,文档提到了jBPM的基本概念。jBPM是一个轻量级流程引擎,它允许开发者以模块化的方式管理业务流程。...

    JBPM 开发指南流程

    ### JBPM 开发指南流程详解 #### 一、概述 JBPM是一个强大的开源工作流引擎,完全基于Java语言开发,并且其持久层采用的是Hibernate框架。这意味着JBPM能够支持所有Hibernate支持的数据库类型,提供了非常高的灵活...

    jbpm jbpm3 jbpm4 用户和开发指南+教程+最佳实践全套

    "jbpm开发指南.pdf"可能是对jbpm4或更高版本的开发者指南,涵盖了jbpm的编程模型、API使用、集成策略等深入内容,帮助开发者构建基于jbpm的业务流程应用。这通常会包括如何使用jPDL(jbpm Process Definition ...

    jbpm4.4 在线设计流程图 ext + raphael

    本教程将深入探讨jbpm4.4的在线设计流程图特性,以及如何利用ext(一个JavaScript UI库)和raphael(一个矢量图形库)进行流程图的绘制与交互。 首先,jbpm4.4中的在线设计流程图功能依赖于ext库,它提供了丰富的...

    用raphael实现的jbpm4web流程设计器

    标题中的“用raphael实现的jbpm4web流程设计器”提到了两个主要概念:Raphaël和jbpm4web。这两个是IT行业的特定技术,接下来我们将深入探讨它们。 Raphaël是一个JavaScript库,主要用于在Web浏览器中创建矢量图形...

Global site tag (gtag.js) - Google Analytics