`
man1900
  • 浏览: 429000 次
  • 性别: 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)

相关推荐

    JBPM4 开发文档 实例 流程

    JBPM4 开发文档 实例 流程 JBPM4 开发文档 实例 流程 JBPM4 开发文档 实例 流程

    JBPM4介绍开发步骤简介

    JBPM4轻量级,简单初步的基础的开发步骤

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

    关于JBPM中并发子流程的实现方式,网上有很多的说法,但是好像每种办法都有这样那样的缺点,要么实现太复杂,要么就是会使Token无法继续流转。这里我介绍一种我的并发子流程的实现方式:使用TaskNode使任务并行的...

    JBPM5工作流引擎 S2SH+JBPM4.4开发工作流的一个完整的请假流程例子

    JBPM5工作流引擎 S2SH+JBPM4.4开发工作流的一个完整的请假流程例子。带有文档教程和所有源码+JAR包。在网上找了半天jbpm6\jbpm7的资料,都很少。所以 环境:Myeclipse2015 JDK1.7 mysql 5.0 Struts2+Spring3.1 1...

    jbpm web流程设计器-jbpm4_free_v1.2cut 免费版

    大家在做jbpm的时候,肯定会考虑到将工作流提升到用户层面,让用户可以设计流程,而不是只在myeclipse中由程序员设计,这个软件就是这个作用,有需要的人可以下载。 注意:该文件是免费版,具备的功能是:图形化流程...

    JBPM3.2开发基本流程

    文档是自己通过学习JBPM3总结出来的,大家可以参考一下,包括插件的安装,开发流程,学习总结等等!

    JBPM流程引擎资料

    文档详细介绍了如何利用JBPM开发流程应用,从框架构造到节点处理。

    流程开发java插件jbpm 使用说明 个人总结

    流程开发java插件jbpm 使用说明 个人总结工具介绍使用

    jbpm开发工作流程管理

    jBPM最大的特色就是它的商务逻辑定义没有采用目前的一些规范,如WfMC′s XPDL, BPML, ebXML, BPEL4WS等,而是采用了它自己定义的JBoss jBPM Process definition language (jPdl)。jPdl认为一个商务流程可以被看作是...

    jbpm开发指南--jbpm全面介绍

    通过查看JBPM的表,我们知道要实现流程监控功能就是把JBPM当中的JBPM_PROCESSDEFINITION(已发布的流程表),JBPM_PROCESSINSTANCE(流程实例表),JBPM_TASKINSTANCE(流程产生的任务实例表)这三张表串联起来就可以...

    JBPM 流程 监控 的实现

    JBPM是JBOSS公司的一个开源工作流产品,它功能强大,商业工作流所提供的功能它基本上都有。然而在JBPM中没有提供流程监控的功能的相关API,这点让很多使用JBPM做企业应用的开发人员颇为头疼。

    jbpm开发步骤

    jBPM 4的 Eclipse 开发插件 只有GPD 流程设计器(GPD) 图形化流程设计器(GPD)使用Eclipse作为其平台, 并把GPD插件安装到eclipse上。 使用Eclipse软件升级(Software Update)机制安装设计器是非常简单的。 在...

    基于JBPM的企业业务流程开发

    基于JBPM的企业业务流程开发 工作流 基于JBPM的企业业务流程开发

    工作流JBPM开发计划书

    对JBPM工作流进行二次开发,主要包括对JBPM功能的扩展、流程定义工具、流程实例监控工具、工作流控制台、应用程序接口以及组织结构扩展接口的开发。 在次基础上,开发基于工作流系统的办公自动化系统等相应的业务...

    JBPM 开发指南流程

    JBPM是一个扩展性很强的工作流系统,百分百用JAVA语言开发,持久层采用Hibernate实现,理论上说,只要Hibernate支持的数据库JBPM都支持。同时它还能被部署在任何一款JAVA应用服务器上。

    jbpm4.3 开发手册

    jbpm4.3 开发手册,chm格式文档,方便查看。

    jbpm4.4+s2sh请假流程例子

    jbpm4.4整合s2sh 请假流程例子

    extjs实现jbpm工作流流程设计

    使用extjs实现的jbpm工作流设计器,刚设计extjs开发的人员可以很好的借鉴,或者刚好要开发相同功能的拿过去直接改改就可以用了

    第二部分、安装和配置JBPM5.4及Eclipse流程插件安装.rar

    基于java及JBPM5.4流程引擎技术开发.鉴于JBPM5.4版本较新,而目前网上基本上没有对应的简单实例,更不要说负责案例及项目设计。 本课程是在国内没有任何中文文档的情况下,完全靠翻译国外的英文文档并结合项目应用...

    JBPM4工作流应用开始指南.rar

    此外,本篇还可以帮助读者快速上手jBPM4、使用jBPM4开发企业流程应用,包括安装和配置jBPM4、使用jBPM图形化流程设计器(GPD)设计流程、把流程部署到服务器上去、使用jBPM 4 Service API控制流程、掌握jBPM流程定义...

Global site tag (gtag.js) - Google Analytics