当前位置导航:炫浪网>>网络学院>>编程开发>>JAVA教程>>J2EE

JBPM源码解读之:Join

       前面我有一篇《JBPM源码解读之:Fork》,大致分析了JBPM对于Fork的实现方式,其实Fork和Join是不可分割的一对,Fork实现分拆,Join实现汇集。先让我们看一下《JBPM 3.2.3 User Guide》中关于Join的描述:
 The default join assumes that all tokens that arrive in the join are children of the same parent. This situation is created when using the fork as mentioned above and when all tokens created by a fork arrive in the same join. A join will end every token that enters the join. Then the join will examine the parent-child relation of the token that enters the join. When all sibling tokens have arrived in the join, the parent token will be propagated over the (unique!) leaving transition. When there are still sibling tokens active, the join will behave as a wait state.
     下面就让我们从JBPM源码的角度分析一下Join是如何关闭每一个到达它的Token,是如何检查各个子Token与父Token的父子关系,又是如何重新激活父Token实现流程的继续流转,更重要的也是我写这篇文章的原因:我们如何能从Join默认的实现方式中得到启发,让我们能够更好的理解JBPM整个运转流程,更好的驾驭整个项目。

        我们来看Join类的成员变量:

 1      /**
 2      * specifies wether what type of hibernate lock should be acquired. null
 3      * value defaults to LockMode.Force
 4       */

 5     String parentLockMode;
 6
 7      /**
 8      * specifies if this joinhandler is a discriminator. a descriminator
 9      * reactivates the parent when the first concurrent token enters the join.
10      * 注:
11       */

12      boolean  isDiscriminator  =   false ;
13
14      /**
15      * a fixed set of concurrent tokens.
16       */

17     Collection tokenNames  =   null ;
18
19      /**
20      * a script that calculates concurrent tokens at runtime.
21       */

22     Script script  =   null ;
23
24      /**
25      * reactivate the parent if the n-th token arrives in the join.
26       */

27      int  nOutOfM  =   - 1 ;

      parentLockMode用于控制Hibernate的锁机制,这点我们暂且不去深究,有意思的是下面几个变量:isDiscriminator、tokenNames、script、nOutOfM共同决定了Join节点内被的具体行为,本文稍后会具体解说。

1 public   void  read(Element element, JpdlXmlReader jpdlReader)  {
2         String lock  =  element.attributeValue( " lock " );
3          if  ((lock  !=   null &&  (lock.equalsIgnoreCase( " pessimistic " )))  {
4             parentLockMode  =  LockMode.UPGRADE.toString();
5         }

6     }

    Join的read方法很简单,只是起到了读取JPDL中对lock的配置,并没有关心其他成员变量的初始化,这也就直接说明了isDiscriminator、tokenNames、script、nOutOfM这几个变量均属于运行期,也就是我们没有办法在配置文件里头像Fork一样配置Script,就算配了Join也不认。

    execute(ExecutionContext executionContext)方法是每个继承自Node的类的核心方法,Join类也是在这个方法中实现了Join的控制机制。在解读这个方法之前必须应该明白的一件事是:Join的execute方法就像Fork的Node-Leave 事件一样是会执行多次的,同样这取决于与Join搭配的Fork具体产生了几个子Token.

 1        // 取得Token
 2         Token token  =  executionContext.getToken();
 3          // 得到Token的isAbleToReactivateParent属性
 4          boolean  isAbleToReactivateParent  =  token.isAbleToReactivateParent();
 5
 6          // 如果当前Token没有结束,则结束该Token,到这里Fork产生的子Token的生命周期也就结束了
 7          if  ( ! token.hasEnded())  {
 8             token.end( false );
 9         }

10          // 检查该Token是否具有激活父Token的能力,如果有方法继续,如果没有方法结束。
11          if  (isAbleToReactivateParent)  {
12             
13         }

    Join的这种处理方式,让我们可以方便的实现一种生活中经常用到的抄送机制,例如:在某个流程中有一个审批的环节,这个审批的默认执行人为李副处长,既定情况下,如果这位李副处长审批完毕,流程就应该继续,但是现在王正处长要求所有审批过的文件都要自己亲自过目,但是只是过目,王处长的这个“过目”的行为要求并不会影响流程的运行,意思就是说,王处长完全有可能在流程都已经结束过了才去过目。稍后我会另有文章具体介绍我的使用Fork+Join实现抄送的思路。

共3页 首页 上一页 1 2 3 下一页 尾页 跳转到
相关内容
赞助商链接