• 1. 第五章 工作流执行服务1
  • 2. 主要内容工作流执行服务 流程定义解析 jBPM中的设计模式 流程实例的运行2
  • 3. 5.1 工作流执行服务5.1.1 工作流执行服务的结构 5.1.2 分离关注点 5.1.3 访问外部资源的方式 5.1.4 工作流执行服务的拓扑方式 5.1.5 工作流引擎的职责3
  • 4. 5.1.1 工作流执行服务的结构工作流执行服务是工作流管理系统的心脏 解释业务流程定义、创建新的流程实例 基于流程定义生成活动或任务实例 匹配任务和资源 支持活动的执行并记录流程实例运行状况 工作流执行服务的结构 4
  • 5. 5.1.2 分离关注点逻辑上的关注点分离 流程定义和活动控制逻辑的分离:活动控制逻辑构成了工作流执行服务;而流程定义用于描述现实业务。 流程定义和应用程序工具、终端用户任务的分离:应用程序工具和终端用户任务对应每个活动的处理过程。 5
  • 6. 5.1.3 访问外部资源的方式客户端应用程序接口(The client application interface) 通过这个接口,工作流引擎可以与任务表处理器交互,代替用户资源来组织任务。任务表处理器从任务表中选择任务项,并推动任务项的执行。应用程序工具的调用则由任务表处理器或终端用户负责。 应用程序调用接口(The invoked application interface) 该接口允许工作流引擎直接激活一个应用程序工具,来执行一个特定的活动。一个典型的应用就是没有用户接口的基于服务器的应用程序。如果某个特定的活动执行需要和终端用户进行交互,那么应用程序工具通常由工作流表接口来调用,这样做的好处是用户任务的调度更具弹性。采用标准接口进行工具调用,将来的应用程序工具便可以以标准的方式进行交互。 6
  • 7. 5.1.4 工作流执行服务的拓扑方式在物理拓扑上或逻辑拓扑上,工作流执行服务可以是集中式的,也可以是分布式的。在分布式的工作流执行服务中,每个工作流引擎控制流程执行的一部分,并与这部分流程中的活动或任务所涉及到的用户、应用程序工具等资源进行交互。 分布式的工作流执行服务必须具备公共的命名空间与管理范围,以便采用一致的方式处理流程定义、用户和应用程序。在工作流引擎之间采用特殊的协议和信息转换格式,分布式工作流管理系统便可以同步工作流引擎的操作、交换流程和活动的控制信息。另外,工作流相关数据也需要在工作流引擎之间传递。在单构的工作流执行服务中,所有以上的操作都是厂商独立定义、开发的。 7
  • 8. 5.1.5 工作流引擎的职责解释流程定义; 控制流程实例的创建、激活、挂起、终止等操作; 控制活动或任务实例的创建、激活、挂起、终止等操作; 在流程活动之间导航; 参与者登录和退出; 确定需要用户参与的任务项,并提供与用户交互的接口; 维护工作流相关数据,并在应用程序或参与者之间传递工作流相关数据; 提供调用外部程序和访问工作流相关数据的接口; 提供控制、管理和审计功能; 记录流程实例运行的历史数据。 8
  • 9. 5.2 流程定义解析5.2.1 流程定义转换接口 5.2.2 jBPM的流程定义转换接口 5.2.3 解析流程定义文档 5.2.4 动作节点解析 5.2.5 任务节点和任务解析9
  • 10. 5.2.1 流程定义转换接口流程定义转换接口属于工作流参考模型的接口1 。 流程定义转换的过程:10
  • 11. 5.2.1 流程定义转换接口采用标准的流程定义格式的好处 分离了流程建立期环境和运行期环境,使得采用同一个建模工具生成的流程定义,可以作为多个不同工作流执行服务的输入。这就允许用户独立的选择流程建模工具和工作流运行期产品。这一特性增强了用户对工作流管理系统的选择范围和配置管理程度。客户可以根据自身的业务特点选择符合工作流管理联盟的、来自于不同软件供应商的产品,进而组成一个完整的工作流管理系统。 提供为多个不同工作流产品输出流程定义的能力,这些工作流产品能够互相协作,并提供分布式的工作流执行服务。11
  • 12. 5.2.2 jBPM的流程定义转换接口流程定义解析接口Parsable jBPM流程定义转换接口的实现位于jBPM发布包的org.jbpm.jpdl包中。 为了实现流程元素的解析工作,jBPM中所有流程节点元素必须实现org.jbpm.jpdl.xml.Parsable接口。 Parsable接口的结构:12
  • 13. 5.2.2 jBPM的流程定义转换接口使用dom4j解析流程定义 jPDL文档由dom4j(dom4j 是一个解析XML 文档的开放源代码XML 框架)负责解析,然后根据解析所得的流程元素和属性创建相应的图形对象。 jPDL文档是一个包含根元素process-definition的XML文档树。 Parsable接口和节点类的关系: 13
  • 14. 5.2.3 解析流程定义文档解析方式 字符串形式的流程定义文档 以归档文件形式存放的流程定义文档 以XML文件形式存放的流程定义文档 流程定义类ProcessDefinition的方法 parseXmlString()常在测试时使用,用于测试简单的、以字符串形式表示的业务流程; parseXmlResource()、parseXmlInputStream()和parseXmlReader()可以直接解析以文件形式存放的流程定义文档; parseParResource()和parseParZipInputStream()用于解析以归档文件形式存放的流程定义。 14
  • 15. 5.2.3 解析流程定义文档解析过程 使用JpdlParser将流程定义文档转换为一个DOM对象树; 读取并设置流程定义的基本属性; 读取、解析并创建参与者(swimlane)对象; 读取、解析并创建动作(Action)对象; 读取、解析并创建节点类型对象; 读取、解析并创建事件(event)对象; 读取、解析并创建异常处理器(exception handler)对象; 读取、解析并创建任务(task)列表。 读取流程定义的内容,比如:动作、节点和异常处理器等对象; 解析流程定义DOM树中未解析的内容,校验参与者与任务的对应关系。 15
  • 16. 5.2.4 动作节点解析动作节点类型代表业务流程中的业务节点,能够实现自动运行的任务,比如:更新数据库,向其它系统发送消息等。在流程定义图形上,业务节点仅代表一个业务功能点。为实现动作节点的业务功能,软件设计人员可以采用动作和事件修饰动作节点。 动作节点能够包含零个或一个动作元素和多个事件元素,而且一个事件可以容纳多个动作实现。如果流程定义中存在动作节点,那么jBPM首先解析动作节点,生成动作节点对象;然后,根据动作节点元素的内容,依次解析动作实现元素和事件元素。如果动作节点元素设置了多个动作实现,则只取第一个动作实现为节点的动作,而忽略其它动作元素。事件元素中的动作则不受此限制。 16
  • 17. 5.2.5 任务节点和任务解析任务节点能够容纳多个需要和参与者交互的任务。如果流程定义中包含任务节点: jBPM首先解析任务节点元素 然后根据流程定义的内容依次解析任务节点中的任务列表,并将任务与特定的参与者绑定起来。 定义参与者的方式: 使用Swinlane定义,这类似于UML活动图中的泳道 使用代理类委托实现,此时代理维护一个实现了AssignmentHandler接口的任务分配处理器。 17
  • 18. 5.3 jBPM中的设计模式5.3.1 jBPM中的命令模式 5.3.2 jBPM中的责任链模式 5.3.3 jBPM命令链模式18
  • 19. 5.3.1 jBPM中的命令模式命令模式 命令模式(Command Pattern)属于对象的行为模式。 命令模式把一个请求或者操作封装到一个对象中,把发出命令的责任和执行命令的责任分离开,然后把请求委派给不同的对象。 命令模式将请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求如何被接收、操作是否执行、何时被执行以及是怎么被执行的。 19
  • 20. 5.3.1 jBPM中的命令模式使用命令模式的好处 操作的执行取决于命令的接收方; 便于在系统中加入新的命令; 可以方便的实现命令队列; 能够实现请求的撤销和恢复。20
  • 21. 5.3.1 jBPM中的命令模式 动作Action是命令模式的实现 命令角色:声明所有具体命令的抽象接口。在jBPM中,该角色由命令处理器ActionHandler接口提供,其中execute()方法为执行方法。 具体命令角色:一个实现了ActionHandler接口及其execute()方法的类,是命令的具体实现。用于在命令接收者与动作行为之间解耦。该角色通常由软件设计人员根据具体业务功能定义并实现。 请求者角色:请求者负责调用命令,以执行一个请求。与请求者相关的方法叫做行动方法。在jBPM中,请求者角色由类Action实现。 接收者角色。接收者负责具体实施和执行一个请求,用来反映动作的执行效果。在jBPM中,接收者角色由流程执行上下文ExecutionContext扮演。具体命令可操作该上下文,获取流程实例的相关信息,并操作流程实例。 客户角色:客户角色用来创建一个具体命令实例并确定其接收者。在jBPM中,动作节点可扮演客户角色。 21
  • 22. 5.3.1 jBPM中的命令模式jBPM中命令模式的结构22
  • 23. 5.3.1 jBPM中的命令模式动作Action的使用过程就是命令模式的实现过程 一个具体命令代表业务流程中的一项具体业务。动作节点反映业务流程的执行逻辑,而将逻辑的实现交给动作,即实现逻辑由具体命令处理。 业务流程建模时,只需在流程定义中为动作节点设置具体命令的类全限定名称,便可实现命令请求和命令实现的分离。流程实例运行时,流程的节点元素只需发出命令请求,剩余的业务功能实现则有具体命令负责处理。 23
  • 24. 5.3.1 jBPM中的命令模式使用命令模式的好处 使用命令模式,可以分离任务的创建工作和任务的分配工作,彼此相对独立。只有在创建任务实例时,才为任务实例指定参与者。任务分配处理器的修改不会影响整体业务流程,便于业务流程的扩展和重构。 对于动作而言,使用命令模式实现的好处与任务分配类似。动作和流程定义相互分离,业务流程负责业务逻辑的执行顺序,而动作负责业务逻辑的具体实现。比如:在网上购物流程中,如果更换了物流公司,只需修改向物流公司发送邮件通知的动作实现就可以了。 24
  • 25. 5.3.2 jBPM中的责任链模式责任链模式 责任链模式是对象的行为模式。在责任链模式中,每个对象都有对下一个对象的引用,顺次连接,形成一条对象链。请求在这个对象链上传递,直到链上的某一个对象决定处理此请求。在整个过程中,客户并不知道这个请求将由对象链上的哪一个对象处理,而且系统可以在不影响客户端的情况下动态的重新组织对象链或者分配责任。对象链上的对象可以选择处理接收到的请求,也可以把请求传递给下一个对象。 责任链可以是一条直线、一个环或者是一个树形结构。通常情况下,责任链模式涉及两种角色:抽象的处理器角色和具体的处理器角色。其中抽象的处理器角色定义一个标记方法,用于设定、返回下一个对象的引用;具体的处理器角色是抽象处理器角色的实现,用于处理接收到的请求或将请求继续传递个下一个对象。 25
  • 26. 5.3.2 jBPM中的责任链模式抽象的处理器角色由节点类Node实现。 其它图形元素,比如:开始节点、任务节点、角色节点和等待节点等,代表了具体处理器角色的实现。26
  • 27. 5.3.3 jBPM命令链模式jBPM根据流程定义生成流程实例。流程实例运行时,首先创建主令牌。在流程实例执行过程中,令牌在不同的节点中传递,直到进入结束节点为止。 jBPM实现了命令模式和责任链模式,分别负责分离命令、传递请求的责任。 jBPM的命令链模式是命令模式和责任链模式的合成,而命令链中的令牌就是命令模式和责任链模式中的请求。 在jBPM命令链中,除等待节点外,所有的节点都可以传递令牌。也就是说:令牌在流程定义的节点中传递,直到进入等待节点。令牌代表流程实例的执行路径,令牌包含一个对当前节点的对象引用,用来表示该令牌当前所处的位置。节点功能执行完毕后,节点放弃该令牌,然后选择一个可用的变迁向下传递该令牌。27
  • 28. 5.4 流程实例的运行5.4.1 令牌Token 5.4.2 运行流程实例 5.4.3 流程实例的状态模型 5.4.4 节点实例的状态模型 5.4.5 让动作节点动起来 5.4.6 流程执行上下文 5.4.7 事件的处理 5.4.8 处理流程运行中的异常28
  • 29. 5.4.1 令牌Token在jBPM中,令牌Token代表流程实例运行的路径,用来维护流程实例的运行状态。 在结构上,流程实例的所有令牌是一棵以主令牌为根的树。 令牌的结构:29
  • 30. 5.4.1 令牌Token流程实例的令牌在结构上是一棵以主令牌为根的树 当流程实例执行并发节点时,流程的执行路径被分成多条子路径,并派生出多个子令牌,分别指向子路径的第一个节点。多个子令牌分别代表多条流程执行子路径,这些子路径彼此独立的运行,直到进入合并节点。 合并节点回收这些子令牌,并将子令牌合并为一条执行路径,然后继续执行流程实例的剩余节点。 30
  • 31. 5.4.1 令牌Token令牌在流程实例中的流转过程 31
  • 32. 5.4.2 运行流程实例流程实例的三种生成方式 ProcessInstance pi = new ProcessInstance(pd); ProcessInstance pi = new ProcessInstance(pd, map); ProcessInstance pi = new ProcessInstance(pd, map, “key");32
  • 33. 5.4.2 运行流程实例流程定义必须包含一个开始节点 在jPDL描述中,一个流程定义只能包含一个开始节点,而且必须包含一个开始节点。 流程实例运行的主令牌是伴随着流程实例的创建而初始化的,如果没有开始节点,主令牌找不到主入口,就会抛出异常,导致流程实例无法运行。 在流程定义类ProcessDefinition中,只能包含一个开始节点。这就意味着:如果流程定义中包含了多个开始节点定义,则除第一个开始节点能被解析外,其他的定义都将被忽略。 33
  • 34. 5.4.3 流程实例的状态模型工作流参考模型定义的流程实例运行状态34
  • 35. 5.4.3 流程实例的状态模型jBPM工作流模型定义的流程实例运行状态35
  • 36. 5.4.4 节点实例的状态模型工作流参考模型定义的活动实例运行状态36
  • 37. 5.4.4 节点实例的状态模型jBPM工作流模型定义的节点实例运行状态 37
  • 38. 5.4.5 让动作节点动起来在流程实例执行过程中,如果动作节点包含了动作实现,则需要使用ProcessInstance类的signal()方法或Token的signal()方法触发,动作节点才会交出令牌,并离开当前节点,进入下一个节点; 如果动作节点没有附带动作,则直接通过默认变迁向下传递令牌。 在使用动作节点处理用户自定义的业务操作时,必须亲自管理令牌的传递动作。在业务操作完成后,手工释放令牌,并选择合适的路径向下传递令牌。 38
  • 39. 5.4.6 流程执行上下文流程执行上下文的结构 ExecutionContext维护流程实例的相关信息,是节点之间流转必不可少的通信媒介。 流程执行上下文ExecutionContext封装了流程实例、令牌、任务、变迁、事件和动作实现等对象实例的引用。39
  • 40. 5.4.6 流程执行上下文流程执行上下文在动作Action实现中的使用方法 除了用户自定义的动作实现和任务分配处理器实现外,在流程实例执行过程中,流程执行上下文ExecutionContext对用户是不可见的。 public class ExecutionContextAction implements ActionHandler { public void execute(ExecutionContext executionContext) throws Exception { // 直接使用ExecutionContext …… } }40
  • 41. 5.4.7 事件的处理事件定义了流程实例执行过程中特定时刻能够发生的事情。 在流程实例执行过程中,jBPM工作流引擎根据图形元素执行的时间点,依次触发定义的事件,并执行事件中包裹的动作实现。 事件的触发点位于节点的进入和离开时刻、任务的创建、分配、开始和结束时刻,或者位于流程实例触发(执行signal()方法)的前后。 41
  • 42. 5.4.7 事件的处理为图形元素定义事件 事件通常和一个图形元素相关联,这些图形元素可以是包括开始节点、动作节点、变迁和决策节点等所有类型的图形元素。 不同的节点类型支持的事件类型是不同的。 事件可以包含多个动作实现,当事件被触发时,工作流引擎将逐个执行该事件中包裹的动作实现。 42
  • 43. 5.4.8 处理流程运行中的异常在流程实例执行过程中,不可避免的会产生异常。这些异常通常来自流程定义中的动作实现(ActionHandler实现)、任务分配器实现(AssignmentHandler实现)或表达式,而流程执行本身不会产生异常。 异常处理器ExceptionHandler能够处理流程运行过程中产生的异常。在jBPM中,流程定义可以包含一组ExceptionHandler,其中每一个ExceptionHandler处理一种特定的异常类型。同时,每一个ExceptionHandler可拥有一组动作实现,以便在发生异常时,能够执行相应的动作。43
  • 44. 5.4.8 处理流程运行中的异常 44
  • 45. 总结 工作流执行服务是工作流管理系统的核心组件,用于解析流程定义,提供流程实例的运行期环境,并为用户提供管理流程定义和流程实例的接口。而流程实例则是业务流程的一次执行,是业务流程在现实场景中的真实运行。 45