jbpm4.0:jBPM-4.0中文开发指南-第7章 高级图形执行

  第 7 章 高级图形执行

   7.1. 循环

   活动可以实现循环基于转移或活动组合 循环可以包含等待状态

   为了支持多次自动循环执行流程虚拟机 把执行传播从尾部递归转换成while循环

   7.2. 子流程

   TODO: 子流程

   7.3. 默认执行行为

   当个Activity被用作活动行为 它可以使用下面思路方法从外部控制流程:

   * waitForSignal

   * take(Transition)

   * end(*)

   * execute(Activity)

   * createExecution(*)

   当Activity实现用做活动行为 没有任何下面流程传播思路方法然后 在活动执行时执行会使用默认执行行为

   默认执行行为定义在下面:

   * 如果当前活动有个默认向外转移选择它

   * 如果当前活动有个父活动回退到父活动

   * 否则结束这个执行

   流程语言可以重写默认执行行为 通过重写ExecutionImpl中 proceed思路方法

   7.4. 功能活动

   活动也可以用作事件监听器被称作功能活动 自动活动例子是发送邮件执行数据库更新 生成pdf计算平均数等等 所有这些都是自动活动没有改变执行流向 这里是这些活动如何实现:

public FunctionalActivity implements Activity, EventListener {
    public void execute(ActivityExecution execution) {
      perform(execution);
    }
    public void noty(EventListenerExecution execution) {
      perform(execution);
    }
    void perform(OpenExecution execution) {
      ...do functional work...
    }
  }


   perform思路方法获得个OpenExecution 这是ActivityExecution和 EventListenerExecution超类 OpenExecution没有提供任何特定目思路方法 但是依旧是当前状态流程定义可以通过变量检验 这包含了环境信息 对应流程执行

   这些思路方法其实都不能执行传播思路方法 所以在perform思路方法完成后执行会 执行默认方式

  7.5. 执行和线程

   这章解释流程虚拟机如何通过客户端线程个执行从个等待状态带到另

   当个客户个执行个思路方法(比如signal思路方法) 默认流程虚拟机会使用线程执行流程 直到它到达个等待状态旦下个等待状态到达 这个思路方法会返回客户端线程就会返回 这是流程虚拟机操作默认方式 两个更多异步执行可以补充默认行为: 异步继续 和异步命令服务

   下个流程会展示基本理论 它有 3个等待状态和 4个自动活动

   有很多顺序自动活动流程



   图 7.1. 有很多顺序自动活动流程

   这里是如何构建流程:

ClientProcessDefinition processDefinition = ProcessFactory.build("automatic")
    .activity("wait 1").initial.behaviour( WaitState)
      .transition.to("automatic 1")
    .activity("automatic 1").behaviour( Display("one"))
      .transition.to("wait 2")
    .activity("wait 2").behaviour( WaitState)
      .transition.to("automatic 2")
    .activity("automatic 2").behaviour( Display("two"))
      .transition.to("automatic 3")
    .activity("automatic 3").behaviour( Display("three"))
      .transition.to("automatic 4")
    .activity("automatic 4").behaviour( Display("four"))
      .transition.to("wait 3")
    .activity("wait 3").behaviour( WaitState)
.done;


   让我们和你起顺着流程执行起走

  ClientExecution execution = processDefinition.startProcessInstance;

   启动个新执行意味着活动被执行 所以如果个自动活动是活动这意味着第个未命名向外转移会被立刻选择 这些都发生在startProcessInstance内部

   然而在这种情况下活动是个等待状态 所以startProcessInstance思路方法会立刻返回 执行会定位到活动'wait 1'.个新执行会被定为到'wait 1'.

  

   图 7.2. 个新执行会被定为到'wait 1'.

   然后个外部触发器会执行signal思路方法

  execution.signal;

   像上面解释介绍WaitState signal会导致选择默认转移 转移会把执行移动到automatic 1活动并执行它 automatic 1中Display活动execute思路方法 向控制台打印它不会 execution.waitForSignal() 因此执行会通过选择automatic 1外部默认转移进行执行 在这种状态signal思路方法直阻塞着个需要考虑方式是执行思路方法 像signal会使用客户端线程 来拦截流程定义直到到达个等待状态

   然后执行到达wait 2 执行WaitState活动那个思路方法会 execution.waitForSignal()这会导致signal思路方法返回 线程会返回到signal思路方法 客户端

   所以当signal思路方法返回时执行定义到wait 2.个signal会把执行从'initial'带到'wait 2'.

  

   图 7.3. 个signal会把执行从'initial'带到'wait 2'.

  然后执行会等待个外部触发器 像是个对象(更准确个对象图)在内存中 直到下个外部触发器执行signal思路方法

  execution.signal;

   第 2个signal会直接让执行进入wait 3 在它返回的前

   第 2个signal让执行进入'wait 3'.

  

   图 7.4. 第 2个signal让执行进入'wait 3'.

   使用这个范例好处是相同流程定义可以在 客户执行模式中执行 (在内存内不使用持久化)就像在持久化执行模式 依赖应用和环境

   当在持久化模式下执行个流程你如何绑定 流程执行到数据库事务上

   持久化模式下事务超时

  

   图 7.5. 持久化模式下事务超时

   在大多情况下计算工作是流程需要完成部分 在外部触发器(红色部分)的后部分其实很少 般来说处理流程执行和处理UI传递过来请求 事务不会超过 而业务流程中等待状态可能超过几小时几天甚至几年 当等待状态启动后线索就变得很清晰 在等待状态启动的前只有计算工作完成包含在事务中

   考虑下这种方式: "当到达审批时所有自动流程需要做是什么 在流程系统需要等待另个外部触发器的前?". 除非pdf需要被创建或大邮件需要被发送 大部分时候它消耗时间都是可以忽略 这就是为什么在默认持久化执行模式下 流程工作在客户端线程下执行

   这个原因也保证着流程同步路径情况个执行单独路径切分成流程同步路径 流程花在计算上时间是可忽略 所以为什么分支或切分活动实现是有意义 目标持久化模式产生同步路径在同个线程中按顺序执行 基本上它们都只是在同个事务中计算工作 分支或切分知道每个执行同步路径会返回所以这只能被完成 当出现个等待状态时候

   这里有个困难概念需要掌握我会再次使用其他词语来解释它 从头再看次在持久化执行模式下被流程执行创建出来 如果在个事务中个执行被给和个外部触发器 那导致执行切分成多个执行同步路径 然后执行在计算上部分也可以忽略 生成SQL部分也可以忽略 所有在同步分支上完成功能必须在同个事务中完成 这里般没有指针在分支或切分实现 在多个线程中产生执行同步路径

   为了创建可执行流程开发者需要确切知道什么是自动活动 什么是等待状态哪些线程会被分配给流程执行 对于画业务流程业务分析人员事件就很简单了 对于他们画活动他们通常只要知道这是个人或是个系统响应 但是他们通常不知道如何转换线程和事务

   所以对于开发者个任务是分析什么是流程控制线程中需要执行 什么是外部 查找外部触发器是寻找个流程中等待状态很好开始 就像动词和名词可以在构建UML类图中元素规则

  7.6. 流程同步

   为了进行流程同步建模在执行中这是个父子树形结构 这个想法是执行主路径是树 流程主路径也被称作流程例子 当在给定流程定义上启动或创建个新流程例子时 执行便被创建

   现在执行主路径和流程例子是相同对象 这保证了使用方法简单 在没有同步情况简单流程下

   基本执行结构UML类图

  

   图 7.6. 基本执行结构UML类图

   为了建立执行多同步路径活动实现比如个分支或切分 创建子执行 使用ActivityExecution.createExecution思路方法 活动实现比如结合或合并可以停止流程这些同步路径 通过执行同步stop思路方法

   只有叶子执行可以激活非叶子执行应该不是激活 这个执行树形结构没有坚持个同步或结合行为特殊类型 它从事着分支或和切分 和结合或和合并来使用执行树结构 用任何方式他们想定义期望同步行为 这里我们看个同步执行例子

   执行同步路径

  

   图 7.7. 执行同步路径

   这里有执行个付款和个发货路径 在这种情况水平线上活动展示了分支和结合这个执行显示了 3个执行 执行主路径不是激活(显示成灰色) 执行付款和发货路径是激活分别指向了 bill和ship活动

   从事活动行为实现是他们想使用执行结构 假设多个任务必须在执行进行的前完成 活动行为可以为这个产生系列子执行 或者可以选择任务组件可以支持任务组 分配给单独执行在那种情况 任务组件成为同步任务响应 因此把这个责任移动到执行树形结构范围的外

  7.7. 异常处理器

   在所有分配到流程代码中像 ActivityEventListeners和 Condition可能分配给异常处理器 这可以想成是把这些实现思路方法实现包含在try-catch块中 但是为了构建更多可复用构建块 为了委派类和异常处理逻辑 异常处理器可以添加到核心流程模型中

   个异常处理器可以分配给任何流程元素个异常发生在个委派类中个匹配异常处理器就会被找到 如果找到了个这样异常处理器它会有个处理这个异常机会

   如果个异常处理器处理完成没有出现问题然后这个异常会 被认为是处理了就会在委派代码后继续 比如个转移有 3个动作第 2个动作抛出个异常 这个异常被异常处理器处理然后

   编写自动活动异常处理器提醒是很容易 默认是任意执行没有思路方法需要在执行中 所以如果个自动活动抛出个异常被异常处理器处理 这个执行会在这个执行后继续执行这对于控制流向活动 就会有个更大困难它们可能需要包含try-finally块 来执行中对应思路方法在异常处理器 获得个机会来处理异常比如如果活动是等待状态 然后发生了个异常这里就会有个风险线程会跳出 execution.waitForSignal() 导致执行在这个活动以后继续执行

   TODO: exceptionhandler.isRethrowMasked

   TODO: transactional exception handlers

   TODO: we never catch errors

   7.8. 流程修改

   TODO: 流程修改

   7.9. 锁定和流程状态

   个执行状态不是激活就是锁定 个激活执行不是执行就是等待外部触发器 如果个执行不是STATE_ACTIVE那么它就是被锁定 个锁定执行是只读不能接受任何外部触发器

   当个新执行被创建时它是STATE_ACTIVE. 为了把状态修改成锁定状态使用lock(String)些STATE_*常量 被提供了它们演示了最常用锁定状态 但是在图片中'……'状态展示了任何串 都可以作为状态提供给lock思路方法

   执行状态

  

   图 7.8. 执行状态

   如果个执行被锁定修改执行思路方法会 抛出个PvmException信息会引用真实锁定状态 触发事件更新变量更新优先级添加注释 不会当做是修改执行 子节点创建和删除也不会检测 这意味着那些思路方法可以被外部API客户和活动行为 即使执行在锁定状态

   确保比较getState()和STATE_*常量时 使用equals不要使用''如果执行从持久存储加载 会创建个新而不是使用常量

   个执行实现会被锁定:

   * 当它结束

   * 当它暂停

   * 在异步延续过程中

   更多锁定可以被活动实现使用 让执行在等待状态下只读然后为这个执行传递 外部例子就像这样:

   * 个人员任务



   * 个服务

   * 个等待状态当探测器检测个文件出现时就结束

   在这些情况策略是外部例子应该获得 执行完全控制它想要控制什么应该允许什么不应该 为了获得那种控制他们锁定了执行所以所有内部交互 必须通过外部例子传递

   个创建外部例子主要原因是 它们可以在执行已经执行过还存在比如 在服务情况定时器可以导致执行获得超时转移 当响应在超时后到达服务例子应该 确认它没有signal这个执行所以服务可以看做 个活动例子(活动例子) 是对活动每个执行例子

   外部例子它们自己负责管理执行锁定 如果定时器和客户端应用结果是选择 外部例子而不是直接选择执行然后在理论上是不必要 它是从事活动行为实现无论它希望 执行锁定还是解锁



Tags:  jbpm4.0

延伸阅读

最新评论

发表评论