82
JBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 1.1. 1.2. The JBoss jBPM 新手工具箱 1.3. The JBoss jBPM 流程 设计 1.4. The JBoss jBPM 核心 1.5. The JBoss jBPM 控制台 web 1.6. The JBoss jBPM 1.7. The JBoss jBPM 日程安排程序 1.8. The JBoss jBPM 兼容 1.9. The JBoss jBPM BPEL 2. 2.1. 2.1.1. jBPM 3 2.1.1.1. 新手工具箱 2.1.1.2. 核心引擎和身 2.1.1.3. 库扩 2.1.2. jBPM 流程 设计 2.1.2.1. Eclipse 更新站 2.1.2.2. Eclipse 2.1.3. jBPM BPEL 2.2. The JBoss jBPM 目目 2.3. CVS 访问 3. 指南 3.1. Hello World 例子 3.2. 例子 3.3. 上下 ( context) 例子 : 流程 3.4. 分派例子 3.5. 定制 Action 例子 4. 面向 的程序 设计 4.1. 缺少的一 4.2. 解表示和 开发过 4.3. 习惯 方法 4.4. 是面向 的程序 设计 4.5. 5. 5.1. 的相 部分 5.1.1. Java 5.1.2. jBPM 5.1.3. 需要的 5.2. 配置文件 5.2.1. jbpm.properties 5.2.2. Hibernate cfg xml file 5.2.3. 业务 配置文件 5.2.4. 量映射配置 5.2.5. 转换 器配置文件 5.2.6. 缺省模 配置文件 5.2.7. 流程文 解析器配置文件 5.3. Web 用程序中使用 jBPM 5.4. EJB 包容器中使用 jBPM 6. 永久化 6.1. 永久化 API 6.2. 配置 6.3. 管理事 6.4. jBPM 6.4.1. Hibernate 集成 JBoss jBPM 3.0 下一

JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

  • Upload
    others

  • View
    40

  • Download
    0

Embed Size (px)

Citation preview

Page 1: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

JBoss jBPM 3.0

Workflow and BPM 实践

目录

1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱 1.3. The JBoss jBPM 流程图形设计器 1.4. The JBoss jBPM 核心组件 1.5. The JBoss jBPM 控制台web应用 1.6. The JBoss jBPM 身份组件 1.7. The JBoss jBPM 日程安排程序 1.8. The JBoss jBPM 兼容数据库包 1.9. The JBoss jBPM BPEL 扩展

2. 开始 2.1.下载一览

2.1.1. jBPM 3 2.1.1.1. 新手工具箱 2.1.1.2. 核心引擎和身份组件 2.1.1.3. 数据库扩展

2.1.2. jBPM 流程设计器 2.1.2.1. Eclipse 更新站点 2.1.2.2. Eclipse 特点

2.1.3. jBPM BPEL 扩展 2.2. The JBoss jBPM 项目目录 2.3. 公开CVS访问

3. 指南 3.1. Hello World 例子 3.2. 数据库 例子 3.3. 上下问(context) 例子: 流程变量 3.4. 任务分派例子 3.5. 定制动作Action例子

4. 面向图的程序设计 4.1. 缺少的一环 4.2. 图解表示和开发过程 4.3. 习惯方法 4.4. 什么是面向图的程序设计 4.5. 组建块

5. 发布 5.1. 运行时的相关部分

5.1.1. Java运行环境 5.1.2. jBPM 库 5.1.3. 运行时需要的库

5.2. 配置文件 5.2.1. jbpm.properties 5.2.2. Hibernate cfg xml file 5.2.3. 业务日历配置文件 5.2.4. 变量映射配置稳健 5.2.5. 转换器配置文件 5.2.6. 缺省模块配置文件 5.2.7. 流程文档解析器配置文件

5.3. 在Web应用程序中使用jBPM 5.4. 在EJB 包容器中使用jBPM

6. 永久化 6.1. 永久化API 6.2. 数据库配置 6.3. 管理事务 6.4. jBPM数据库

6.4.1. Hibernate集成

JBoss jBPM 3.0

下一页

Page 2: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

6.4.2. 开发数据库是hsqldb 6.4.3. 其他数据库的支持 6.4.4. 高速缓冲存储器

6.5. Hibernate 定制 7. 流程模型

7.1. 综述 7.2. 流程图(process Graph) 7.3. 节点(Nodes)

7.3.1. 节点(Node)职责 7.3.2. 节点类型(Nodetype)任务(task-node) 7.3.3. 节点类型(Nodetype) 状态(state) 7.3.4. 节点类型(Nodetype) 判定(decision) 7.3.5. 节点类型(Nodetype) 分叉(fork) 7.3.6. 节点类型(Nodetype) 联合(join) 7.3.7. 节点类型(Nodetype) 节点(node)

7.4. 动作(Actions) 7.4.1. 动作配置 7.4.2. 动作引用 7.4.3. 事件 7.4.4. 事件传播 7.4.5. Script 7.4.6. 定制事件

7.5. 超状态(superstate) 7.5.1. 超状态 变迁 7.5.2. 超状态 事件 7.5.3. 分级名字

7.6. 异常处理 7.7. 流程组成 7.8. 定制节点行为 7.9. 图(Graph)执行

8. 上下文(Context) 8.1. 存取变量 8.2. 变量的使用期限 8.3. 变量永久化 8.4. 变量范围

8.4.1. 变量重载( overloading) 8.4.2. 变量重写 (overriding)

8.5. 瞬间变量 8.6. 定制变量永久化

9. 任务管理 9.1. 任务 9.2. 任务实例

9.2.1. 任务实例生命周期 9.2.2. 任务实例及图执行

9.3. 委派(Assignment) 9.3.1. 委派接口 9.3.2. 委派数据模型 9.3.3. "推"模型 9.3.4. "拉"模型

9.4. 泳道(Swimlanes) 9.5. 任务 事件 9.6. 任务 定时器 9.7. 任务 控制器 9.8. 定制 任务实例 9.9. 身份组件

9.9.1. 身份模型 9.9.2. 赋值表达式

9.9.2.1. 第一个术语 9.9.2.2. 下一个术语

9.9.3. 删除身份组件 10. 调度程序

10.1. 定时器 10.2. 调度程序发布

11. 业务日历 11.1. 持久时间 11.2. 配置

12. 记录 12.1. 建立日志 12.2. 日志检索

Page 3: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

12.3. 数据仓库 13. jBPM 流程定义语言 (JPDL)

13.1. 流程档案 13.1.1. 发布流程档案 13.1.2. 流程版本(versioning) 13.1.3. 流程转换(conversion)

13.2. 代理 13.2.1. jBPM类载入器 13.2.2. 流程类载入器(class loader) 13.2.3. 代理配置

13.2.3.1. 配置类型 field 13.2.3.2. 配置类型 bean 13.2.3.3. 配置类型 constructor 13.2.3.4. 配置类型 configuration-property

13.3. JPDL xml schema 13.3.1. process-definition(流程定义) 13.3.2. node(节点) 13.3.3. common node elements(常见节点元素) 13.3.4. start-state(开始状态) 13.3.5. end-state(结束状态) 13.3.6. state(状态) 13.3.7. task-node(任务节点) 13.3.8. process-state(流程状态) 13.3.9. super-state(超状态) 13.3.10. fork(交叉) 13.3.11. join(联合) 13.3.12. decision(判定) 13.3.13. event(事件) 13.3.14. transition(转换) 13.3.15. action(动作) 13.3.16. script(脚本) 13.3.17. expression(表达式) 13.3.18. variable(变量) 13.3.19. handler(处理器) 13.3.20. timer(定时器) 13.3.21. create-timer(建立定时器) 13.3.22. cancel-timer(放弃定时器) 13.3.23. task(任务) 13.3.24. swimlane(泳道) 13.3.25. assignment(委派) 13.3.26. controller(控制器) 13.3.27. sub-process(子流程) 13.3.28. condition(条件) 13.3.29. exception-handler(异常处理)

14. 安全 14.1. 要做的 14.2. 验证 14.3. 授权

15. TDD for workflow 15.1. Introducing TDD for workflow 15.2. XML sources

15.2.1. Parsing a process archive 15.2.2. Parsing an xml file 15.2.3. Parsing an xml String

15.3. Testing sub processes 16. 可插入架构

下一步

Chapter 1. 介绍

Page 4: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第一章:介绍

JBoss jBPM 是一个复杂的可扩展的工作流管理系统. JBoss jBPM 有直观的流程语言来表示商业流程图的术语比如,任务,异步通

讯的等待状态,定时器,自动操作等等.把这些操作绑在一起,, JBoss jBPM 就有了最强大和易扩展性的控制流机制.

JBoss jBPM 只有最小的倚赖性可以很容易的作为java库来使用.当然它也可以用在吞吐量极为关键的J2EE 群应用服务器环境中.

JBoss jBPM 可以同任何数据库配置可以部署在任何应用服务器上.

1.1. 综述

核心工作流和BPM 功能被封状作为一个简单的Java库.这个库包括在jBPM数据库中存储,更新和检索流程信息的服务

Figure 1.1. JBoss jBPM 组件一览

1.2. JBoss jBPM 新手工具箱

新手工具箱是包含了jBPM所有组件包在一个可下载的包里.

这个包包括:

jbpm-server , 预先配置的jboss 应用服务器. jbpm-designer , jBPM流程图形化设计器的eclipse 插件 . jbpm-db , jBPM 数据库兼容包 (参看下面). jbpm , 核心jbpm组件包括库和本手册. jbpm-bpel , JBoss jBPM BPEL 扩展参考.

第一章:介绍

前一页 后一页

Page 5: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

预配置的JBoss 应用服务器有下列安装组件:

核心jBPM 组件 , 打包作为JBoss服务档案

一个包括所有jBPM 表格的完整数据库 : 默认的 hypersonic 数据库包含所有的jBPM 表格和已经定义的流程. jBPM 控制台web应用程序 这个可以用来为jBPM管理员. jBPM调度程序 所有定时器的执行. 调度程序在新手工具箱里配置成了一个servlet.这个Servlet会为产生一个线程来监视每个定

时器的执行. 一个流程例子 已经发布进了jBPM 数据库.

1.3. JBoss jBPM 图形化流程设计器

JBoss jBPM 也包括一个图形化的流程设计工具. 这个设计器是用来创作商业流程的

JBoss jBPM 图形设计器是一个Eclipse插件. 独立安装版本的设计器工具已经在开发路线图里了.

图形化设计工具最重要的特性是它同时支持业务分析员和技术开发人员. 这样就可以在业务流程建模和实际执行之间平滑转换.

插件可用做为本地的update site(Eclipse 纯粹的zip文件),用做符合Eclipse软件更新机制的安装包. 当然你也可以把它展开到你

的Eclipse的安装目录.

1.4.JBoss jBPM核心组件

JBoss jBPM 核心组件是纯粹的Java(J2SE)软件,来处理流程定义和运行时的流程实例执行.

JBoss jBPM 是一个Java库. 因此,它可以用在任何java环境比如web 应用程序,Swing应用程序,EJB,Web Service等等. jBPM 库可以被打包作为sateless session EJB(无状态会话EJB). 这可以用做集群的发布具有极高的吞吐量可伸缩性. 无状态会话EJB根据J2EE 1.3规范重新写过所以可以发布到任何应用服务器上.

JBoss jBPM 核心组件被打包成一个简单的Java库文件.依赖你所使用的功能性, 库 jbpm-3.0.jar及一些相关的第三方的库比如 . hibernate, dom4j 等等. 这些相关性在 第五章发布 有清晰的描述

永久性方面, jBPM内部使用hibernate. 除了传统的O/R 映射外, hibernate也分析不同数据库系统的SQL方言 ,这使jBPM在当

前所有的数据库上都可以移植.

JBoss jBPM API 可以从项目中任意编写的Java软件访问,比如Web应用程序,EJB,或web Service组件,消息bean或其他java组件.

1.5. JBoss jBPM控制台web应用程序

jBPM 控制台web应用程序是为两个目的服务的.首先,它作为流程执行运行时间任务生成的中央用户接口. 其次, 它也是一个管理

和监视控制台允许检查和操作运行中的流程实例.

1.6. JBoss jBPM 身份组件

JBoss jBPM可以集成进任何包含公司用户和组织信息的目录. 对项目来说从那里得到组织信息组件不是容易得到的, JBoss jBPM就包含这个组件. 身份组件使用的模型比通常的servlet,ejb和门户模型跟富有.

更多信息可参考 章节9.9, “身份组件”

1.7. JBoss jBPM 调度程序

JBoss jBPM 调度程序是用来监视和运行已经计划到时执行流程的定时器的组件.

定时器组件被打包在核心jbpm库中, 但是它需要被发布到下面的任一环境中: 要不你把调度程序Servlet来产生监视线程或者就必

须用独立的JVM来调用调度程序的main方法.

Page 6: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

1.8. JBoss jBPM 数据库兼容包

JBoss jBPM 数据库兼容包包括所有支持数据库的相关信息,JDBC驱动程序和数据库初始化脚本.

1.9. JBoss jBPM BPEL扩展

JBoss jBPM BPEL扩展是独立的扩展包用来支持BPEL(Business Process Execution Language 商业流程执行语言). BPEL的基本要素是 xml Scripting语言用来写其他web server的web services.

前一页 Up 后一页

JBoss jBPM 3.0 首页 第二章:开始

Page 7: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第二章 开始

本章将带你如何获得JBoss jBPM的第一步并且提供立即运行的初始提示 .

2.1. 下载包一览

下面是当前可用的不同jBPM包清单. 这些包中的每一个都包含一个或多个可下载的文件. 同这些文件一起的包含一个描述它的内容及相关安装的指示

所有下面下载的描述都可以在 the sourceforge jbpm 下载页面.上找到

2.1.1. jBPM 3

这是主要的发行包,包括了主要核心引擎和数个额外的你使用jBPM的时候可能用得上的包.下载这个包的文件从 这里.

2.1.1.1. 新手工具箱

如果你想尽快开始运行jBPM,那么这就是你想下载的文件.工具箱包含了所有jBPM的模块以及图形化的设计工具在一个单独下载

的文件里名字为: 'jbpm-starters-kit-<version>.zip'. 展开这个压缩文件到目录下阅读'readme.html' 获取更多信息. 有了这

个工具箱,你可以立即开始进入 第三章 讲座.

2.1.1.2. 核心引擎和身份组件

下载文件名为 'jbpm-<version>.zip' 包含jBPM 核心引擎也包含角色和组管理的身份组件. 开始工作前, 展开文件到一个目录

下,然后 'jbpm-<version>'文件夹下找到包含重要的参考信息的'readme.html'文件

2.1.1.3. 数据库扩展

如果你想改变jBPM的默认数据库( Hypersonic HSQLDB), 你需要下载这个包. 文件名为'jbpm-db-<version>.zip' 包含你改

变数据库需要的各种资源. 包含, 数据库建立脚本, hibernate 属性文件及数据库JDBC驱动程序. 如何操作的步骤包含在

'readme.html' 文件里,它在你展开这个压缩包的最上层的目录下.

2.1.2. jBPM 流程设计器

The second package contains the downloads related to the jBPM Graphical Proces Designer. The designer enables you to author your process definitions and to easily deploy them. You can find these downloads here.The designer is a plug-in for the Eclipse platform which is available for download either as a zipped Eclipse feature or as a zipped Eclipse update site. There is no difference in content, the only difference is in the way you have to do the installation.

2.1.2.1. Eclipse 更新站点

If you want to be absolutely sure that the designer installation goes smoothly, we recommend to use the update site mechanism together with a new Eclipse installation. Of cource the Eclipse version should match the downloaded update site archive. To obtain the Process Designer Update Site, you should download the file 'jbpm-gpd-site-<version>.zip'. Then follow the instructions in the 'readme.html' file included in the archives root folder to succesfully install the GPD.

2.1.2.2. Eclipse 特性

If you are tired of each time having to do a fresh Eclipse installation and you are willing to cope with some possible issues, you can try the feature download. In this case installation is as easy as extracting the archive

第二章 开始

前一页 后一页

Page 8: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

into your Eclipse installation (make sure the included 'plugins' and 'features' folders end up in the same location of your Eclipse installation) overwriting the files and folders with the same name that are possibly already present. This installation is very easy, but you could run into incompatibility issues when you overwrite plugins already present in your installation because of other features that you did install. Though they have the same name it could happen that the versions of these colliding plugins are not equal, hence the possible incompatibilities. Download the file 'jbpm-gpd-feature-<version>.zip' to obtain the GPD feature. The installation instructions are repeated in the 'readme.html' file.

2.1.3. jBPM BPEL 扩展

第三个也是最后一个包包含jBPM BPEL 扩展. 它只包含一个文件: 'jbpm-bpel-<version>.zip'. 你可以找到这个包 在这里 .要开始BPEL扩展,在doc目录下找到User's Guide .

2.2. JBoss jBPM 项目号码簿

professional support: JBoss is the company that backs this project with professional support, training and consultancy services. user guide: is the document you're reading and serves as the main entry point into the project. download descriptions: description of the downloadables downloads: sourceforge download page for jBPM forums: get in contact with the community, ask questions and discuss jBPM wiki: extra information, mostly provided by the community issue tracker: for submitting bugs and feature requests roadmap: shows what to expect in the next versions mailing lists: mailing lists are used for announcements javadocs: part of the download in the doc/javadoc directory. cvs: the details of how to get the jBPM sources from CVS

2.3. 公开的CVS访问

另外,你可以通过JBoss jBPM cvs服务器 得到jBPM

服务器的信息如下

Connection type: pserver User: anonymous Password: Host: cvs.sourceforge.net Port: 2401 (which is the default) Repository path: /cvsroot/jbpm Label: :pserver:[email protected]:/cvsroot/jbpm

前一页 Up 后一页

Chapter 1. Introduction Home Chapter 3. Tutorial

Page 9: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第三章. 讲座

这个讲座将展示如何建造一个jpdl和如何使用API的方法来管理运行时的执行.

这个讲座的方式是解释一系列的例子. 每个例子将集中关注特别的主题和额外的说明. 这些例子可以在jBPM包的examples目录

下找到.

好的方法就是学着来建立一个Project实验所给的例子.

eclipse 用户注意:下载jbpm-3.0-[version].zip并且解压缩到系统. 然后从菜单 "File" --> "Import..." --> "Existing Project into Workspace". 点 "Next" 然后浏览jBPM 根目录然后点击 "Finish". 现在你的有了jbpm 3 project了. 你可以发

现这个讲座目录在目录 src/java.examples/... . 你打开这些例子后,可以运行它们"Run" --> "Run As..." --> "JUnit Test"

jBPM 包括一个图形设计器来产生例子中的XML. 你可以从这里下载和学习有关图形设计器的说明 节 2.1, “下载一览”

3.1. Hello World 例子

一个流程 是有一个定向图(directed graph)来定义,由节点和变换组成 . hello world 流程有3个节点.如下看如何组合起来, 我们先开始一个简单的流程不使用图形设计器. 下面的图形表示hello world 流程:

Figure 3.1. hello world 流程图

public void testHelloWorldProcess() { // 这个方法展现流程定义和流程执行的定义

// 流程定义有3个节点. // 一个未命名的开始状态start-state,一个状态 's' // 一个结束状态名字为'end'. // 下面行解析一个xml text为一个ProcessDefinition对象(流程定义) // ProcessDefinition 把流程定义形式描述为java对象

ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( "<process-definition>" + " <start-state>" + " <transition to='s' />" + " </start-state>" + " <state name='s'>" + " <transition to='end' />" + " </state>" + " <end-state name='end' />" + "</process-definition>" ); // 下一行建立了一个流程执行定义. //在构造后,流程执行有一个主要的执行路径

// (= root token 根令牌) 此时位置在start-state处

ProcessInstance processInstance = new ProcessInstance(processDefinition); // 在构造后流程执行有一个主要的执行路径

// (= roottoken 根令牌) .

第三章. 讲座

前一页 后一页

Page 10: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Token token = processInstance.getRootToken(); // 构造后, 位置处于流程定义执行路径start-state的位置

assertSame(processDefinition.getStartState(), token.getNode()); // 现在开始流程执行,离开start-state 结束默认的转换(transition) token.signal(); // 这个signal方法将会阻塞直到流程执行进入 wait 状态

// 流程执行在状态's' 进入第一个 等待状态

// 因此执行主路径现在位置在 状态's' assertSame(processDefinition.getNode("s"), token.getNode()); // 我们再送另外一个信号signal. 这将继续执行离开状态's' 结束默认的转换(transition) token.signal(); // 现在信号signal方法将返回,因为流程实例到达了end-state 结束状态

assertSame(processDefinition.getNode("end"), token.getNode()); }

3.2. 数据库例子

jBPM一个基本的特性是当流程处于等待状态时候可以把流程执行 永久化到数据库中 . 下一个例子想你展示了如何存储一个流程

实例到jBPM数据库中. 例子给出一个将会发生的上下文.分开的方法用来建立不同部分的用户代码. 比如一部分用户代码在web 应用程序中开始一个流程并永久化执行到数据库中.然后,message drive bean从数据库中载入流程实例并继续它的执行

jBPM 永久化的更多内容可以参看 第六章, 永久化.

public class HelloWorldDbTest extends TestCase { // 我们在每个应用程序中需要一个JbpmSessionFactory. 因此我们把它放在一个静态变量中

// JbpmSessionFactory 在test 方法中来建立一个

JbpmSession's. static JbpmSessionFactory jbpmSessionFactory = JbpmSessionFactory.buildJbpmSessionFactory(); static { // 因为HSQLDBin-memory数据库是干净的数据库, // 在我们开始测试前,我们需要建立table. // The next line creates the database tables and foreign key // constraints. jbpmSessionFactory.getJbpmSchema().createSchema(); } public void testSimplePersistence() { // 在3个方法调用下面方法中间,所有数据被写入数据库

// 在单元测试中,这3个方法被正确执行在每个方法之后

// 因为我们想完成测试流程场景

// 但在实际中这些方法代表着server不同的请求

// 因为我们开始的数据库是个干净的数据库,我们需要首先发布流程在里面

// 在真实中,这个是由流程开发人员完成的

deployProcessDefinition(); // 假定我们想开始流程实例(= 流程执行) // 当用户提交一个Web表单的时候. processInstanceIsCreatedWhenUserSubmitsWebappForm(); // 然后,到达的异步消息将继续执行

theProcessInstanceContinuesWhenAnAsyncMessageIsReceived(); } public void deployProcessDefinition() { //定义一个流程,包括三个及点,一个未命名的start-state,一个状态's' //一个结束状态 end-state名字'end'. ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( "<process-definition name='hello world'> + " <start-state name='start'> +

Page 11: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

" <transition to='s' /> + " </start-state> + " <state name='s'> + " <transition to='end' /> + " </state> + " <end-state name='end' /> + "</process-definition> ); // 打开新的永久层会话

JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession(); // 并且在永久层会话上开启事务

jbpmSession.beginTransaction(); // 保存流程定义到数据库中

jbpmSession .getGraphSession() .saveProcessDefinition(processDefinition); // 提交事务

jbpmSession.commitTransaction(); // 关闭会话. jbpmSession.close(); } public void processInstanceIsCreatedWhenUserSubmitsWebappForm() { // 这个方法里的代码可以放在structs action或JSF管理bean 里

// 打开一个新的永久层会话

JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession(); // 启动事务. jbpmSession.beginTransaction(); // 查询数据库得到我们在上面步骤发布的流程定义

ProcessDefinition processDefinition = jbpmSession .getGraphSession() .findLatestProcessDefinition("hello world"); // 有了从数据库中的得到的processDefinition, //我们就可以建立流程执行定义比如hello world 例子(它没有永久化). ProcessInstance processInstance = new ProcessInstance(processDefinition); Token token = processInstance.getRootToken(); assertEquals("start", token.getNode().getName()); // 开始流程执行

token.signal(); // 流程在状态's'. assertEquals("s", token.getNode().getName()); // 流程实例被保存在数据库

// 所以当前流程执行的状态被保存进数据库

. jbpmSession .getGraphSession() .saveProcessInstance(processInstance); // The method below will get the process instance back out // of the database and resume execution by providing another // external signal. // web应用程序动作结束出,事务被提交. jbpmSession.commitTransaction(); // 关闭jbpmSession. jbpmSession.close(); } public void theProcessInstanceContinuesWhenAnAsyncMessageIsReceived() { // 这个代码可以包含在message driven bean中. // 打开新的永久性的会话.

Page 12: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession(); // 永久化会话上开始事务

// 说明它也可能使用应用服务器的DataSource的JDBC连接

jbpmSession.beginTransaction(); GraphSession graphSession = jbpmSession.getGraphSession(); // First, we need to get the process instance back out of the database. // There are several options to know what process instance we are dealing // with here. The easiest in this simple test case is just to look for // the full list of process instances. That should give us only one // result. So let's look up the process definition. ProcessDefinition processDefinition = graphSession.findLatestProcessDefinition("hello world"); // 现在,我们搜索这个流程定义的所有流程实例. List processInstances = graphSession.findProcessInstances(processDefinition.getId()); // We know that in the context of this unit test there is // only one execution. In real life, the processInstanceId can be // extracted from the content of the message that arrived or from // the user making a choice. ProcessInstance processInstance = (ProcessInstance) processInstances.get(0); // 我们可以继续执行. 说明流程实例委托信号到执行主路径(= the root token) processInstance.signal(); // 在singal后, 我们知道流程执行应该到 end-state assertTrue(processInstance.hasEnded()); // 现在我们可以更新执行状态到数据库中

graphSession.saveProcessInstance(processInstance); // MDB结束, 事务被提交. jbpmSession.commitTransaction(); // jbpmSession被关闭. jbpmSession.close(); } }

3.3. 上下文例子: 流程变量

在流程执行时候流程变量包含上下文信息. 流程变量同java.util.Map相似映射名字到值,值可能是个java对象 . 流程变量被永久

化作为流程实例的一部分. 为了让事情简单,这个例子中我们仅仅展示使用变量的API而没有永久化.

关于变量的更多信息可以参看 第8章 上下文

// 这个例子也是从hello world 流程开始. // 甚至没有修改. ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( "<process-definition>" + " <start-state>" + " <transition to='s' />" + " </start-state>" + " <state name='s'>" + " <transition to='end' />" + " </state>" + " <end-state name='end' />" + "</process-definition>" ); ProcessInstance processInstance = new ProcessInstance(processDefinition); // 从流程实例中为流程变量获得上下文实例

ContextInstance contextInstance = processInstance.getContextInstance();

Page 13: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

// 在开始之前流程离开了start-state, // 我们准备设置一些流程变量在流程实例上下文中

. contextInstance.setVariable("amount", new Integer(500)); contextInstance.setVariable("reason", "i met my deadline"); // 从现在开始,这些变量同流程实例关联

// 流程变量可以从用户代码中通过下面展示的API来访问

// 可可以在动作Action和节点的实现中访问

// 流程变量也作为流程实例的一部分保存进数据库

. processInstance.signal(); // 访问变量通过contextInstance. assertEquals(new Integer(500), contextInstance.getVariable("amount")); assertEquals("i met my deadline", contextInstance.getVariable("reason"));

3.4. 任务分派例子

在下个例子里我们将要展示你怎么才能分派一个任务给一个用户.因为jBPM工作流引擎和组织模型是分开的,一种用来计算参与者

表达语言总是受限的. 因此,你不得不指定AssignmentHandler的实现来计算任务的参与者.

public void testTaskAssignment() { // 这个流程展示基于hello world 流程. // 状态节点被task-node代替.task-node在JPDL中是表示一个等待状态并且

// 产生一个在流程继续执行前要完成的任务

ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( "<process-definition name='the baby process'>" + " <start-state>" + " <transition name='baby cries' to='t' />" + " </start-state>" + " <task-node name='t'>" + " <task name='change nappy'>" + " <assignment class='org.jbpm.tutorial.taskmgmt.NappyAssignmentHandler' />" + " </task>" + " <transition to='end' />" + " </task-node>" + " <end-state name='end' />" + "</process-definition>" ); // 产生一个流程执行定义. ProcessInstance processInstance = new ProcessInstance(processDefinition); Token token = processInstance.getRootToken(); // 开始流程执行,完整默认的转换后离开start-state . token.signal(); // signal 方法将被阻塞知道流程执行进入等待状态. // 在这个case中是指task-node. assertSame(processDefinition.getNode("t"), token.getNode()); // 当执行到达task-node, 任务'change nappy' // 被建立并且NappyAssignmentHandler 被调用来决定任务将分派给睡

//NappyAssignmentHandler 返回'papa' // 在真实环境中, 任务将会从数据库中获取,通过or g.jbpm.db.TaskMgmtSession. // 因此这个例子中我们不想包括复杂的永久化

// 我们只是得到这个流程实例的第一个task-实例

(we know there is only one in this test // 我们知道在这个测试场景中这里只有一个). TaskInstance taskInstance = (TaskInstance) processInstance

Page 14: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

.getTaskMgmtInstance() .getTaskInstances() .iterator().next(); // 现在,我们检查taskInstance实际分配给了'papa'. assertEquals("papa", taskInstance.getActorId() ); //现在,我们期望'papa'完成了他的任务并且标记任务是完成的

taskInstance.end(); // 因为这是 后(唯一的)要做的任务,这个任务的完成触发

// 流程实例的继续执行. assertSame(processDefinition.getNode("end"), token.getNode()); }

3.5. 客户化动作例子

动作action是绑定你自己的定制java代码和jBPM流程的一种机制. 动作可以同它自己的节点关联起来 (如果它们在流程图表示中

相关). 动作也可以放在事件event上比如. taking a transition, leaving a node 或者 entering a node.在这个case ,动作不

是图表的一部分,但是它们在流程执行产生事件的时候,也会被执行.

我们将用一个例子: MyActionHandler 来观察动作的实现.这个动作handler实现不是什么非常特别的事情.它只是设置boolean变量 isExecuted 为 true . 变量 isExecuted 是静态的因此它可以在action handler内部被访问.

关于动作action的内容可以参看 7.4节, “动作”

// MyActionHandler 就是一个class可以在jBPM流程执行时候在某些用户代码里被执行

public class MyActionHandler implements ActionHandler { // 在测试之前, isExecuted 被设置为

false. public static boolean isExecuted = false; // 动作将设置true 因此 当动作被执行

// unit test 将会展示

public void execute(ExecutionContext executionContext) { isExecuted = true; } }

// 每次测试开始都要设置MyActionHandler 的成员static isExecuted 为

false. public void setUp() { MyActionHandler.isExecuted = false; }

我们将要在转换时开始一个动作

public void testTransitionAction() { // The next process is a variant of the hello world process. // We have added an action on the transition from state 's' // to the end-state. The purpose of this test is to show // how easy it is to integrate java code in a jBPM process. ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( "<process-definition>" + " <start-state>" + " <transition to='s' />" + " </start-state>" + " <state name='s'>" + " <transition to='end'>" + " <action class='org.jbpm.tutorial.action.MyActionHandler' />" + " </transition>" + " </state>" + " <end-state name='end' />" + "</process-definition>" );

Page 15: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

// Let's start a new execution for the process definition. ProcessInstance processInstance = new ProcessInstance(processDefinition); // The next signal will cause the execution to leave the start // state and enter the state 's' processInstance.signal(); // 这里将显示 MyActionHandler还没有被执行

assertFalse(MyActionHandler.isExecuted); // ... and that the main path of execution is positioned in // the state 's' assertSame(processDefinition.getNode("s"), processInstance.getRootToken().getNode()); // The next signal will trigger the execution of the root // token. The token will take the transition with the // action and the action will be executed during the // call to the signal method. processInstance.signal(); // Here we can see that MyActionHandler was executed during // the call to the signal method. assertTrue(MyActionHandler.isExecuted); }

下一个例子是同样的动作,但动作被分别放在 enter-node和 leave-node 事件 .注意节点同转换相比有超过一个事件类型(event type)转换(transition)只有一个事件.

ProcessDefinition processDefinition = ProcessDefinition.parseXmlString( "<process-definition>" + " <start-state>" + " <transition to='s' />" + " </start-state>" + " <state name='s'>" + " <event type='node-enter'>" + " <action class='org.jbpm.tutorial.action.MyActionHandler' />" + " </event>" + " <event type='node-leave'>" + " <action class='org.jbpm.tutorial.action.MyActionHandler' />" + " </event>" + " <transition to='end'/>" + " </state>" + " <end-state name='end' />" + "</process-definition>" ); ProcessInstance processInstance = new ProcessInstance(processDefinition); assertFalse(MyActionHandler.isExecuted); // The next signal will cause the execution to leave the start // state and enter the state 's'. So the state 's' is entered // and hence the action is executed. processInstance.signal(); assertTrue(MyActionHandler.isExecuted); // Let's reset the MyActionHandler.isExecuted MyActionHandler.isExecuted = false; // The next signal will trigger execution to leave the // state 's'. So the action will be executed again. processInstance.signal(); // Voila. assertTrue(MyActionHandler.isExecuted);

前一页 Up 后一页

第二章 开始 Home 第四章 面向图的程序设计

Page 16: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第四章. 面向图的程序设计

当前工作流和业务流程管理(BPM)的总体发展来说是极其零碎的.在一些工具,规范和学术界发现很少的统一意见 .传统方法导致笨

重的,单系统把大量的功能包含在一个单一的系统中.

Java开发语言中缺少的特性导致在这个范围产生了完整系列的解决方法. 这个文章将标识缺少的特性并且提出一个简单的解决方

法让java变成面向图的开发语言.面向图的开发语言可以看作是构造工作流,BPM及流程编排通用构造模块.

4.1. 缺少的一环

先从比较高层面来看看当前工作流,BPM和流程编排(或协调)领域的解决方法.

Figure 4.1. 一览工作流,BPM和流程编排

因为现在没有很清晰和被普遍接受的有关工作流,BPM和流程编排(或协调)的定义,我们还是做一些普通的观察

工作流是同人们管理任务 接近的. 重点关注工作流指明的由人完成的任务同流程目标的联系.

业务流程管理(BPM),指把工作流和企业应用集成(EAI)结合起来 . 一个业务流程指明通过人通过一些软件完成的任务及他们如何

互相联系来完成业务流程目标.

流程编排(Orchestration)根据它所处的环境而有显著的不同. 流程编排(Orchestration)语言(像BPEL)是定位于web 服务环

境. 流程编排(orchestration)语言是为web服务所用的编程语言. 这就表明你可以由流程编排来为其他web Serverice 编写新的

web Service. 流程编排语言有控制流结构作为语言的一部分.其他的基本操作需要调用其他的 web services.

现在,我们对这三个领域的一般的期望都有了明显的认识. 对流程来说有等待状态是必须具有的能力.这些流程的在等待状态时必须

能暂停执行.

暂停执行在Java中是不可能的.实际上在Java里暂停和继续一个thread(线程)是可能的 (比如用 Object.wait()和 Object.notify() ).但是由于永久化的原因这同流程的等待状态不是非常匹配.工作流, BPM 和流程编排方法在等待状态时候需要永久化它们的执

行.事实上, 在流程流程中状态的改变对应着服务器上的事务..在这些事务之间暂停执行应该被永久化到数据库中或文件系统里.

第四章. 面向图的程序设计

前一页 后一页

Page 17: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Figure 4.2. Java里缺少的暂停执行的路径.

实际上, Java缺少内置的暂停和永久化的机制是没有什么让人惊奇的. 这是因为Java是构造在诺依曼架构上.基本的特征就是顺

序执行指令. 这篇文章就是呈现一种扩展诺依曼架构来支持暂停和永久化执行的技术.

在这三个领域的产品为了解决上述问题都有从自己的角度来观察的方法, . 作为结果,每一个解决组合暂停执行的方法都包含了所

有的可用功能. 这就是让开发社区感到不清楚和混乱的根本原因..

4.2. 图形表示和开发流程

在我们开始处理暂停执行的解决方法之前有一个方面是什么重要的必须引起重视:流程的图形表示.

暂停执行的这个技术能力产生了非常有趣的机会 : 两个业务流程之间的直接连结及技术实现. 业务流程是业务分析需求确定中的

中心部分. 没有暂停执行的机制, 业务流程的需求实现需要复杂转换成软件设计. 这种情况下,开发者不的不在等待状态保存某些形

式的执行状态到数据库中.如此的复杂性会因为业务的功能需求和组合而增加.

结论是如果我们找到一个解决用图形表示的业务流程的执行暂停的方法,将会是一件伟大的事情.. 许多 (可能是全部) 图形化表

示业务流程是基于定向图. 一个流程语言限制成了一个tree,只是定向图的一个子集. 这些语言叫做块结构语言block structured languages .

一个重要的考虑结果提议利用迭代开发. 对UML 类图, 这是常见的联系. 分析员可以用UML类图来画分析模型.然后开发人员用这

个模型作为设计模型的开始点. 然后在实现中加入更多的技术细节. 太多的建议方案 后都是结束于形成一个可视化的开发环境.

4.3. 习惯方法

传统方法是指定一个作为结构集合的流程语言.每一个结构有一个图形表示和运行时的行为.

下面是一般的回顾常用的方法:

Monolithic systems(单一系统) : 传统工作流,BPM 和流程编排orchestration 方法是打包成一个要求独立环境的单一系统.在大多数情况下,这意味着它们很难在你的应用程序中被使用,因为它们在你自己程序范围的外面.. Incomplete process language(不完全的流程语言) : 学术研究 (workflowpatterns.com ) 指出当前所有标准的方案都

有严重的局限,甚至当这个研究范围只是局限在控制流程结构. No modelling freedom(没有建模自由) : 因为图形化表示有之间有固定的连接及流程结构有固定的运行时行为,分析员失去

了自由建模的自由. 结构的绘图包含所有分析员不关心的执行细节. Visual programming(可视化编程) : 因为在图形化表示之间有固定连接及固定的运行时行为,这总是以某种形式的可视化编

程结束, . 根据经验,我知道这是非常消耗时间的编写软件的方式..

4.4. 面向图的程序设计或编程是什么?

面向图的程序设计是解决执行暂停和永久化的问题的技术..因为它的局限范围,这个技术,是容易理解和作为工作流,BPM和流程编

排方法功能的建设模块 .

Page 18: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

面向图的程序设计中心思想是我们为运行时间的图执行用简单的命令式编程.因此图是软件的一部分并且在运行时间图的执行同解

释命令软件紧密偶合的 .

流程图是有节点(nodes)和转换(Transitions)组成.转换(Transitions)有方向并且在图中连接两个节点.

Figure 4.3. 流程是个定向图

图可以看成是一个状态机. 执行模型我们可以解释的比较具体对路径的并发执行有较好的支持.

下面的UML类图勾画了流程元素怎么被建模UML类图中.这也展示了流程图可以被表现为数据(data). 流程图数据可以用不同的方

式表达:XML,java对象,数据库记录...

Figure 4.4. 流程图可以用节点和转换来建模

下一个部分对开发人员和技术人员来说是 难于理解的部分.这是因为我们指明的执行模型同众所周知的 诺埃曼架构 不同.

我们定义一个令牌作为执行路线.它是在一个系统内的执行路线.

Figure 4.5. 令牌是在一个系统内的执行路线

注意流程执行可能包括多个并发的执行路线.我们现在定义一个流程执行作为一个令牌树.令牌在流程图中有个指针指向节点.

Page 19: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Figure 4.6. 流程执行可以表示为一个令牌树

下面的UML类图展示了令牌树如何建模做为UML类图.同样流程执行也能表示为数据.这实际上是使执行永久化的关键部分.

Figure 4.7. 流程执行数据模型

现在,我们来解释java的执行如何同图的执行紧密偶合的. 下一个图形展示了节点和转换中的方法在图执行中是相关的.为了计算下

一个执行状态,我们用一个改良的GOF设计模式中提到的chain of responsibility 模式版本.

Figure 4.8. 图执行是不同的chain of responsibility 模式

图中的节点表示等待状态.在等待状态期间, 一个令牌指到节点.在节点每个令牌可以接受信号signal. 信号可以被送到令牌来再继

续开始执行,之后等待状态结束了.这将使图执行开始.

Page 20: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Figure 4.9. 一个信号触发重新开始图执行

信号的效果使令牌离开节点. 在case中节点有多个离开转换In case the node has more then one leaving transition, 离开

转换必须作为信号的一部分.转换只是使令牌到目的节点.当令牌到达节点,节点被执行.图中每个被定义类型的节点都有运行时间的

行为.每个节点类型对应着节点的子类其行为在excute方法中实现.

节点的execute方法有两个责任.第一, 她执行同节点类型一致的一些业务逻辑,比如.发送一个消息, 更新数据库,为一个用户生成

任务... 第二个责任是节点的execute方法必须传播图执行.如果节点不传播执行,那么它的行为就是等待状态.她可以传播到达节点

的令牌向下到其中的一个离开转换. 或者她可以新建一个令牌然后传播这些向下到离开转换.

当所有令牌进入等待状态的时候图执行就结束了. 在这个时候,信号已经全部处理过了并且流程执行全部完成 (由令牌树组成)全部

进入新的等待状态.此时令牌树可被保持.每个令牌在等待接受另外一个信号.

这个模型需要一个重要的精化 : 动作(action). 动作是在流程事件中执行的一段java代码. 比如事件是'离开节点leaving a node', '进入节点entering a node'和 '取得转换taking a transition'. These 这些都是直接的不能跨越等待状态的事件.

图执行模型用动作action来做精化是必须的,因为这允许技术开发人员可以为商业流程增加执行的细节 , 而不必改变由分析员建立

的原始图.

现在我们小结一下这个模型怎么解决传统工作流,BPM和流程编排的问题.

简单 API + chain of responsibility 模式 : 替代单一系统. 节点继承 : 提供了根本的流程语言力量. 增加了可见的动作 : 给业务分析员建模的自由. 流程开发周期 :替代可视化编程.

4.5. 构建模块(Building blocks)积木

我们提交的这个模型为传统编程添加了支持等待状态. 根据面向图编程我们现在可以定义跨越等待状态的执行路线. 这个模型也可

以用于工作流,BPM和流程编排功能实现的基础.

Page 21: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Figure 4.10. 面向图编程作为构建模块

结构化编程,面向对象编程及面向方面编程(AOP)都可以看作是结构化软件的机制. 面向图编程也可以看作另外一种结构化软件的

机制. 为软件增加结构关键是因为管理的复杂性.因为软件项目的花费同它们的大小成指数关系,因为减少复杂性节省的费用是巨大

的.

前一页 Up 后一页

第三章 指南 Home 第五章 发布

Page 22: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第五章 发布

本章讨论用jBPM库和配置文件的发布问题. 发布流程到jPBM数据库,参看 章节 13.1.1, “发布流程文档”

5.1. 运行相关

5.1.1. Java运行环境

jBPM 3 requires J2SE 1.4.2+

5.1.2. jBPM 库

jbpm-[version].jar 包含核心jbmp功能.

jbpm-identity-[version].jar (可选) 库包含身份组件 章节9.9, “身份组件”.

5.1.3. 运行时间库

核心jBPM代码唯一相关的库是commons logging. 其他的库都是可选的. 当然, xml解析和永久化依赖其他的库.

大多数的jBPM的发布依赖hibernate 3.0 库来做永久化.

表格 5.1.

第五章 发布

前一页 后一页

库 用法 描述 目录

commons-logging-1.0.4.jar

logging in jbpm and hibernate

The jBPM code logs to commons logging. The commons logging library can be configured to dispatch the logs to e.g. java 1.4 logging, log4j, ... See the apache commons user guide for more information on how to configure commons logging. if you're used to log4j, the easiest way is to put the log4j lib and a log4j.properties in the classpath. commons logging will automatically detect this and use that configuration.

lib/hibernate

dom4j-1.6.jar

流程定义和

hibernate 永久化xml解析 lib/hibernate

jaxen-1.1-beta-4.jar

流程定义和

hibernate 永久化xml解析(这个库是dom4j要使用) lib/hibernate

antlr-2.7.4.jar

hibernate 永久化 hibernate查询解析的时候要用来生成解析 lib/hibernate

c3p0-0.8.5.jar

hibernate 永久化

(默认的配置)连接池. When configuring a different connection pooling (e.g. an appserver datasource), this library is not required.

lib/hibernate

cglib-full-2.0.2.jar

hibernate 永久化 code generation library lib/hibernate

commons-collections-2.1.1.jar

hibernate 永久化 lib/hibernate

ehcache-1.1.jar

hibernate 永久化

(in the default configuration)

second level cache implementation. When configuring a different cache provider for hibernate, this library is not required.

lib/hibernate

hibernate3-rc1.jar

hibernate 永久化 the best O/R mapper lib/hibernate

Page 23: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

5.2. 配置文件

JBoss jBPM requires various configuration files. For your convenience the jbpm library jbpm-3.*.jar includes default configuration files that are packaged in the library. When jBPM loads a configuration file, it will always look first in the root directory. If the configuration file is not found in the root directory, it will look in the package directory that contains the default configuration file. So you can overwrite the default configurations by putting a modified configuration file in the root of the classpath.

5.2.1. jbpm.properties

下列属性都是在配置文件jbpm.properties中使用的

Table 5.2.

5.2.2. Hibernate cfg xml file

This file contains hibernate configurations and references to the hibernate mapping resource files.

Location: hibernate.cfg.xml unless specified otherwise in the jbpm.hibernate.cfg.xml property in the jbpm.properties file. In the jbpm project the default hibernate cfg xml file is located in directory src/config.files/hibernate.cfg.xml

5.2.3. Business calendar configuration file

Contains the definition of business hours and free time.

Location: org/jbpm/calendar/jbpm.business.calendar.properties

jdbc2_0-stdext.jar

hibernate 永久化 lib/hibernate

jta.jar hibernate 永久化 lib/hibernate

bsh-2.0b2.jarbeanshell script interpretion

Only used in the script's and decision's. When you don't use these process elements, the beanshell lib can be removed, but then you have to comment out the Script.hbm.xml mapping line in the hibernate.cfg.xml

lib/bsh

属性 默认值 D

jbpm.session.factory.jndi.name

if specified, the JbpmSessionFactowill fetch the singlgiven JNDI locatioJbpmSessionFactoinitialization of the

jbpm.hibernate.cfg.xml hibernate.cfg.xmlthe resource locatconfiguration file

jbpm.hibernate.properties if specified, it will that are specified file.

jbpm.authenticator org.jbpm.security.authenticator.JbpmDefaultAuthenticator

a fully qualified claimplements the org.jbpm.security.interface.

jbpm.authorizer no default (means no authorization is enforced)

a fully qualified claimplements the org.jbpm.security.interface.

jbpm.task.instance.class org.jbpm.taskmgmt.exe.TaskInstancethe fully qualified instances. this allothe task list entrie

Page 24: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

5.2.4. Variable mapping configuration file

Specifies how the values of the process variables (java objects) are converted to variable instances for storage in the jbpm database.

Location: org/jbpm/context/exe/jbpm.varmapping.properties

5.2.5. Converter configuration file

Specifies the id-to-classname mappings. The id's are stored in the database. The org.jbpm.db.hibernate.ConverterEnumType is used to map the ids to the singleton objects.

Location: org/jbpm/db/hibernate/jbpm.converter.properties

5.2.6. Default modules configuration file

specifies which modules are added to a new ProcessDefinition by default.

Location: org/jbpm/graph/def/jbpm.default.modules.properties

5.2.7. Process archive parsers configuration file

specifies the phases of process archive parsing

Location: org/jbpm/jpdl/par/jbpm.parsers.xml

5.3. jBPM in a web application

Simply put the runtime libraries in the WEB-INF/lib folder of your web application archive (.war).

5.4. jBPM 在EJB容器中

JBoss jBPM 可被发布到任何应用服务器. 虽然当前只是在JBOSS应用服务器上测试过.

最简单的方式是把所有 运行时间库 放到你的应用服务器的全局的classpath里.

另外一个办法是, 你可以把 运行时间库 放在 application.xml 并且它们作为库引用.

包含jBPM的新手工具箱作为服务文档.

前一页 Up 后一页

第四章面向图的程序设计 Home 第六章永久化

Page 25: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第六章 永久化

图6.1. 不同形态的转换

流程定义可以用三种不同的形式表现 :xml, java objects 或jBPM数据库记录. 执行信息 (= 运行时间) 和日志信息可表现为2种形式 : java objects 和jBPM数据库记录.

有关XML表示流程定义和流程档案可以参看 第13章, jBPM 流程定义语言 (JPDL).

本章讨论java Object和jBPM数据库之间的转换.jBPM内部hibernate 保存java objects到数据库并且重现他们 . 当然不是严格

限定使用jBPM必须有hibernate 的相关知识,这只是推荐使用hibernate.

更多的有关如何发布流程档案到数据库亲参看 13.1.1节, “发布流程档案”

6.1. 永久化API

图 6.2. The jBPM 数据库class

第六章 永久化

前一页 后一页

Page 26: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

jBPM永久化操作可以根据名字类似 GraphSession, TaskMgmtSession 和 ContextSession等来找到 .从 JbpmSession可以获得命名的会话 . JbpmSession 可以从 JbpmSessionFactory获得.

JbpmSessionFactory 对你的应用程序来说是threadsafe保证的, 你需要一个 JbpmSessionFactory . 单件模式(Singleton)的

延迟初始化(Lazy Initialization)(当心 issues延迟载入和double-check locking的问题 ).

在生成时间, JbpmSessionFactory预备了能让JbpmSession可以飞快建立的所有信息 .

作为一个用户, 你可以为每个thread或每个请求建立一个 JbpmSession . JbpmSession有一个JDBC connection 连接到数据库

JbpmSession 和 JbpmSessionFactory仅仅是包装它们的 hibernate副本. 高级的特性比如独立的数据For advanced features such as 脱管对象(detached objects)或乐观锁定, 参看hibernate文档.

public class PersistenceApiTest extends TestCase { static JbpmSessionFactory jbpmSessionFactory = JbpmSessionFactory.buildJbpmSessionFactory(); public void testStartProcessInstance() { // obtain a session JbpmSession jbpmSession = jbpmSessionFactory.openJbpmSession(); try { // start a user managed transaction jbpmSession.beginTransaction(); // load information from the database // (note that process definitions will be cached in memory // in the second level cache of hibernate) ProcessDefinition auctionProcess = jbpmSession.getGraphSession().findLatestProcessDefinition("auction"); // perform a POJO workflow operation on the plain object model. ProcessInstance auctionInstance = new ProcessInstance(auctionProcess); auctionInstance.signal(); // store the result in the database jbpmSession.getGraphSession().saveProcessInstance(auctionInstance); // commit the user transaction jbpmSession.commitTransaction(); } finally { // close the session. jbpmSession.close(); } } }

6.2. 数据库配置

最容易的配置the hibernate SessionFactory 的方式是把 hibernate.cfg.xml 放到根classpath里. hibernate.cfg.xml 包含了如

何获得jdbc jdbc connections 和定位hibernate mapping 文件. 你可以在目录test/java发现比如mapping文件的例子.

更多关于配置hibernate的信息可以参看 hibernate 参考手册l, 配置章节.

6.3. 管理事务

jBPM 基本方式是平衡 hibernate 关于事务分界的能力. 这有两个最常见的场景来解释:

用户事务管理, JbpmSession 有方法

JbpmSession.beginTransaction() JbpmSession.commitTransaction() JbpmSession.rollbackTransaction()

这些方法的行为依赖hibernate的有关事务的配置.

Page 27: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

如果你配置了hibernate 管理她自己的JDBC connections (比如 C3P0连接池), 那么事务操作的结果同JDBC connection一致. hibernate配置文件中(hibernate.cfg.xml) 配置要求你指明JDBC connection属性. 可选的, 你可以通过c3p0连接池的属

性来配置连接池.

当你配置了hibernate 获得connection从应用服务器中的DataSource,那么事务的方法将同包容器中的UserTransaction object的方法保持一致.

更多有关配置事务的细节参看 hibernate 参考手册, 事务策略章节.

6.4. jBPM 数据库

jBPM 数据库包含流程定义,流程执行和日志数据. 流程定义数据是静态的不能改变(参看 章节13.1.2, “流程版本 . 流程执行是流

程定义的参考数据. 流程日志包含了所有在流程执行中的变化信息.

6.4.1. Hibernate 整合

jBPM 使用 hibernate 3.0 作为它的 O/R映射. 这就意味着hibernate 有负责jBPM java object和这些对象在关系数据库中永

久化对象的变换. 注意你开始使用jBPM不必了解Hibernate . Hibernate用于jBPM内部. 但是理解基本的hibernate, 会帮助你

更好理解jBPM API的语义.

让我们看看一些例子和得到一些hibernate的功能了解:

发布流程档案 : 发布流程档案按照几个步骤, 在第一个步骤, 档案被解析并且相应的java object模型也被建立. 对象图将被

hibernate处理. Hibernate将产生必要的相关SQL数据库插入语句 . 更新流程实例 : 另外一个功能是hibernate 脏数据检查功能. hibernate 在两个对象图中间计算不同并产生必要的对应数据库的

update语句 (和插入及删除) 使java object和数据库保持一致. 因此当你想继续流程执行实例, 你使用 ProcessInstance JbpmSession.getGraphSession().loadProcessInstance(Long pid) , jBPM将委托这个调用到 hibernate. Hibernate将从数据库

载入这个流程实例数据并且结构化成jBPM java objects. 在这之后,你可以自由的修改流程实例java objects就好象其他java objects一样.当你完成 (比如在在执行进入等待状态之后)后 你可以保存修改过的流程实例到数据库,通过调用

JbpmSession.getGraphSession().saveProcessInstance(ProcessInstance processInstance) . jBPM 同样委过这个任务到

hibernate , hibernate 将计算给顶的processInstance和 原始从数据库中载入的processInstance .这叫做脏数据检查. Hibernate 会计算所有的不同并且产生必要的SQL语句来保证数据库和java object的同步.

执行这个任务, hibernate 需要一组mapping文件和配置文件. mapping 文件说明了java object 同数据库table之间的映射. jBPM 包括所有的jBPMdomain class的 mapping 文件.

hibernate配置文件中的主要信息是描述数据库连接的配置属性. 包括jdbc连接和数据库方言. SQL方言是重要的hibernate特性 : 数据库无关. 数据库每个类型一般说来都有同样的SQL, 但不同的数据库有稍微不同的SQL语法. Hibernate 知道这些区别

并通过方言属性来建立正确的SQL. 可以参考hibernate文档查看支持的数据库清单.

6.4.2. 开发数据库是hsqldb

hypersonic数据库是理想的包含关系数据库的java软件的数据库. 尤其是 hypersonic in-memory 模型是非常便于编写包含数

据操作的test unit . hypersonic in-memory 数据库保持所有的数据在内存中而不是保存在磁盘里. jBPM的单元测试将开始一

个干净的空的in-memory数据库. 然后hibernate schema 生成工具将建立jBPM table. 我们提供的jBPM类mapping文件作为

hibernate schema生成器的输入. 然后hibernate schema 生成器根据信息生成数据库schema (DDL)脚本. 这些DDL 语句将

在hypersonic in-memory数据库上执行用来建立新的,空的jBPM 数据库.

6.4.3. 其他数据库支持

为了支持除了hypersonic in-memory 数据库而提供了jbpm 数据库扩展包: jbpm-<version>-db.zip . 参看 章节2.1, “可下

载一览” . 这个包报案ant 脚本来测试jBPM是否为支持的不同的数据库产生数据库的DDL脚本 (create, drop和clean)

在展开 jbpm-<version>-db.zip , 更新 build.properties并且设置 jbpm.3.location 到安装jbpm的主目录(相对路径或绝对路径)

数据包扩展包包括一个ant建造script (build.xml ) 在根目录下. 这个脚本包括建立jBPM支持的数据库生成脚本和测试脚本.运行

ant -p 得到关于建造目标更多的信息. readme.html文件介绍了更多的有关不同数据库实现的信息及状态.

生成的脚本是默认的脚本.如果想为特定的使用定制或优化 , 你必须询问你的DBA 先查看数据库脚本. 通常的定制是额外的索引

或增加text字段的最大值.

Page 28: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

如果你的数据库不被支持,你可以用我们介绍的方法在你的数据库上来测试jBPM . 我们希望支持所有的数据库,所以可以把你的数

据库的下列信息让我们知道.:

jbpm.test.hibernate.properties 配置文件 那里可以下载数据库驱动和数据库版本 你碰到的任何问题

6.4.4. 缓存

TODO

6.5. Hibernate定制

TODO

前一页 Up 后一页

Chapter 5. Deployment Home Chapter 7. Process Modelling

Page 29: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第七章. 流程建模

7.1. 综述

流程定义主要基于定向图表示了一个商业流程的规范.图是有节点和转换组成.图中的每个节点都有一个特定的类型. 节点类型定义

了运行时间的行为.流程定义有且只有一个开始状态.

令牌是执行的一个路线. 令牌是运行时间概念用来维护图中指想节点的指针.

流程实例是一个流程定义执行的实例.当一个流程实例被建立后,一个令牌也为主要执行路线建立了. 这个令牌称为这个流程实例的

根令牌,她的位置处于流程定义的开始状态.

信号指示令牌继续图执行. 当接受到无名的信号,令牌将, 令牌将用缺省的离开转换离开节点. 当转换名字在信号中已经指定,令牌

将使用指定的转换离开节点. 信号发给一个被委托给根令牌的流程实例.

在令牌进入节点后,节点被执行.节点自己有责任连续图执行.图执行的连续是通过让令牌离开节点来完成的.每个节点类型为了连续

图执行实现了不同的行为. 一个节点如果不能传播执行将被认为是一个状态..

动作是在流程执行中在事件上执行的片段java代码. 在社区中有关软件需求方面图是个重要指示.但是图只是一个要生产的软件的

视图(投射). 隐藏了需要技术细节. 动作是一种在图形表示之外增加更多技术细节的机制. 一旦图放在某个地方,它可有动作来修

饰. 主要事件类型是:(进入节点) entering a node,(离开节点) leaving a node 和(执行转换)taking a transition.

7.2. 流程图

基本的流程定义组成是图和节点. 在文件 processdefinition.xml定义 . 每个节点有一个类型state, decision, fork, join,每个节

点有一套离开转换. 可以给离开节点的转换一个名字来区别.比如:下面的图表显示了jBAY拍卖流程的流程图 .

Figure 7.1. 拍卖流程图

下面是jBAY拍卖流程表示的XML:

第七章. 流程建模

前一页 后一页

Page 30: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

<process-definition> <start-state> <transition to="auction" /> </start-state> <state name="auction"> <transition name="auction ends" to="salefork" /> <transition name="cancel" to="end" /> </state> <fork name="salefork"> <transition name="shipping" to="send item" /> <transition name="billing" to="receive money" /> </fork> <state name="send item"> <transition to="receive item" /> </state> <state name="receive item"> <transition to="salejoin" /> </state> <state name="receive money"> <transition to="send money" /> </state> <state name="send money"> <transition to="salejoin" /> </state> <join name="salejoin"> <transition to="end" /> </join> <end-state name="end" /> </process-definition>

7.3. 节点

流程图由节点和转换组成.更多关于图的信息和执行模型,参看 第四章, 面向图的程序设计.

每个接点有一个指定的类型. 节点类型定义当执行到达这个节点的时候将发生什么. jBPM 有一套你可以使用的预实现的节点类型.另外,你可以编写自己的定制代码实现你自己的指定的节点行为.

7.3.1. 节点责任

每个节点有2个主要责任: 首先,它可以执行传统java代码. 典型的传统java代码同节点功能相关. 比如.建立一个新的任务实例, 发送一个通知, 更新数据库,.其次,节点服务传播流程执行.基本上来说,每个节点有下列可选的传播流程执行:

1. 不传播执行. 节点的行为是作为一个等待状态. 2.通过执行节点的一个离开转换来传播执行. 令牌到达节点是通过一个离开转换API executionContext.leaveNode(String). 现在节点作为可执行一些定制程序逻辑及不用等待连续流程执行的自动节点. 3. 建立新的执行路线. 节点可以决定建立新的令牌.每个新令牌表示一个执行的新路线并且没个新令牌可以通过节点的离开转换被

调用.一个很好的例子就是fork(分支)节点模式的行为. 4. 结束执行路线. 节点可以决定结束执行路线.令牌可以结束,也就表示着执行完成了. 5. 更加一般的,节点可以修改流程实例的全部的运行时间结构 . 运行时间结构是包含令牌树的流程实例.每个令牌表示一个执行路

线. 节点可以建立和结束令牌,把每个令牌放在图的节点里并且通过转换来调用..

jBPM 包含--作为任何工作流和BPM引擎-- 一组预先实现的节点类型可有指明配置文件和行为. 但是关于jBPM独特的事情是 面

向图的程序设计基础 对开发者开放的模型. 开发者可以很轻松的写他们自己的节点行为并在流程中使用.

这就使传统的工作流和BPM系统更加接近了. 它们一般提供固定的节点类型(叫做流程语言).它们的流程语言是接近的并且执行模

式在运行时间是隐藏的. 研究 workflow patterns 表明了任何流程处理语言都是不足够强大有力的. 我们必须决定简单模型并且

Page 31: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

允许开发者编写他们自己的节点类型. 这使的 JPDL process 流程语言是可扩展设计的.

下面,我们讨论最重要的JPDL节点类型.

7.3.2. 节点类型 task-node

任务型接点代表一个或多个可以被人执行的任务. 当执行到达一个任务节点,任务实例将在工作流参与者任务清单中被建立. 这之

后,节点将作为一个等待节点. 因此当用户执行他们的任务,任务完成将触发执行继续开始. 换句话说,令牌将调用一个新的信号.

7.3.3. 节点类型 状态(state)

状态是一个单纯(bare-bones)等待状态. 任务节点的不同是没有任务实例在任何任务清单中建立. 这在流程等待外部系统的时候

很有用. 比如.以上的节点入口(通过一个在node-enter事件的动作),一个消息将被送到外部系统. 在这之后, the process will go into a wait state. When the external system send a response message, this can lead to a token.signal(), which triggers resuming of the process execution.

7.3.4. 节点类型 决策(decision)

实际上有两个方法模拟决策. 明显的区别在于基于"谁"来做决策. 或者有流程来做决策 (读: 在流程定义中指明. 或者用外部的实

体提供决策结果.

当有流程来做一个决策的,就要使用一个决策节点了. 有两个基本方式来指明决策的标准.最简单的方式是给转换增加一个条件元

素. 条件是返回结果是boolean的beanshell脚本表达.在运行时间决策代码会被离开转换反复调用(按照XML指定的顺序),来评估

每个条件. 第一个转换在条件是'true'的时候发生. 可选的, 用一个DecisionHandler的实现. 在java class中决策被计算并且被选

择的离开转换由DecisionHandler 实现的决策方法(decide-method)返回.

当决策是由外部部分决定(含义:不是流程定义的一部分), 你可以用多个转换离开状态或等待状态节点. 然后离开转换可以提供外

部的触发在等待状态完成后继续执行.比如 Token.signal(String transitionName) and TaskInstance.end(String transitionName).

7.3.5. 节点类型 分支(fork)

一个分支把一个执行路线分割成多个兵法的执行路线. 默认分支的行为是为每个离开分支转换建立一个子令牌,在令牌要到达的分

支之间建立一个父母-子女 关系.

7.3.6. 节点类型 联合(join)

默认联合(join)假设所有来自同一个父母的子令牌联合.当在上使用fork(分支)这个情形就出现了并且所有令牌分支建立,并且到达

同一个联合(join).当全部令牌都进入联合的时候,联合就结束了. 然后联合将检查父母-子女. 当所有兄弟令牌到达联合(join),父母

令牌将传播(唯一的)离开转换. 当还有兄弟令牌活动时,联合的行为将作为等待状态.

7.3.7. 节点类型 node

类型节点是你想写在节点中写你自己的代码. 节点类型节点期望一个子元素动作.动作(action)在执行到达这个节点时候被执行. 你在actionhandler所写的代码可以做任何事情除了它必须负责 传播执行.

如果你想使用来实现一些对业务分析员来说非常重要的功能逻辑,可以使用节点..当使用节点时,节点在流程图形表示里是可见的.为了对照, 动作(actions) --覆盖着文本-- 允许你加入在图形化流程里看不到的对业务分析员不重要的代码 .

7.4. 动作(Actions)

动作是一段java代码,在流程执行有事件时执行. 图在软件需求社区是重要的指示.但是图只是将要生产的软件的一个视图(投射).它隐藏了技术细节. 动作是在图形化表示之外加入技术细节的机制.当一个图被放置,它可以用动作来装饰. 这就是说java 代码可以

在不修改图结构的情况下和图关联起来. 主要的事件类型是进入节点entering a node,离开节点 leaving a node 和执行转换

taking a transition.

注意事件中的动作和节点中的动作的不同. 事件中的动作当事件发生的时候才执行.事件中的action没有方法影响流程的控制流.可

Page 32: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

以参考以下观察者的设计模式. 另一面,节点里的action有 递执行的责任.

我们看看事件中的动作. 假定我们想在给定的转换上做数据库更新.数据库更新技术上是极其重要的,但对业务分析员来说是不重要

的.

图 7.2. 数据库更新动作

public class RemoveEmployeeUpdate implements ActionHandler { public void execute(ExecutionContext ctx) throws Exception { // get the fired employee from the process variables. String firedEmployee = (String) ctx.getContextInstance().getVariable("fired employee"); // by taking the same database connection as used for the jbpm updates, we // reuse the jbpm transaction for our database update. Connection connection = ctx.getProcessInstance().getJbpmSession().getSession().getConnection(); Statement statement = connection.createStatement("DELETE FROM EMPLOYEE WHERE ..."); statement.execute(); statement.close(); } }

<process-definition name="yearly evaluation"> ... <state name="fire employee"> <transition to="collect badge"> <action class="com.nomercy.hr.RemoveEmployeeUpdate" /> </transition> </state> <state name="collect badge"> ... </process-definition>

7.4.1.动作(Action)配置

关于给你自己定制的动作添加配置和如何在配置文件processdefinition.xml中指明配置的更多信息, 参看 13.2.3章节, “委托的

配置”

7.4.2. 动作(Action)参考

可以给动作起个名字. 命名的动作可以在其他位置通过名字来引用. 命名的动作也可以在流程定义中作为子元素.

这个特点在你想限制重复的动作配置(比如 当动作的配置非常复杂时)的时候就非常有用了.另外一个use case是执行或调度安排

一个运行时间的动作.

7.4.3. 事件(Events)

Page 33: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

事件指明流程执行的时刻. jBPM 引擎在图执行时会产生事件. 这发生在当jbpm 计算下一个状态(请看: 生成信号). 事件总是同一

个流程定义中的元素相关,比如流程定义,节点或转换.绝大多数流程元素能产生不同类型的事件. 举例的节点可产生 node-enter(节点进入)事件和 和一个节点离开 node-leave事件 .事件是同动作挂钩的. 每个时间有一个动作清单.当jBPM引擎产生一个事

件,动作清单就会被执行.

7.4.4. 事件传送Event propagation

超状态根据流程定义生成一个父母-子女关系. 节点和转换包含在一个以超状态为父母的超状态里. 最顶级的元素以流程定义作为

父母. 流程定义没有父母.当事件被生成, 事件将被向上传送到父母层.这允许在一个流程中一个中心可以捕捉所有的转换事件和同

这些事件关联的动作.

7.4.5. Script

脚本是动作执行的beanshell脚本. 更多有关beanshell参看 the beanshell website . 默认的所有流程变量作为脚本变量

script-variables和非脚本变量no script-variables 被写到流程变量process variables. 所有可用的脚本变量:

executionContext token node task taskInstance

<process-definition> <event type="node-enter"> <script> System.out.println("this script is entering node "+node); </script> </event> ... </process-definition>

定制载入和储存到脚本的默认行为, variable 元素可以被用做为脚本子元素.在这个case, 脚本表达式也被放入脚本子元素: expression.

<process-definition> <event type="process-end"> <script> <expression> a = b + c; </expression> <variable name= 'XXX' access= 'write' mapped-name = 'a' /> <variable name='YYY' access='read' mapped-name='b' /> <variable name='ZZZ' access='read' mapped-name= 'c' /> </script> </event> ... </process-definition>

在脚本开始之前,流程变量 YYY 和 ZZZ 将分别作为脚本变量b和c可用. 当脚本完成后, 脚本变量的值被储存进流程变量 XXX.

如果变量的 access属性包含 'read ', 流程变量可以在评估之前载入作为脚本变量. 如果 access属性包含 'write ', 在评估之后

脚本变量被存储为流程变量. 属性 mapped-name可以使流程变量在脚本中用另外一个名字被访问 . 这在你的流程变量包含空

格或其他非法的文字字符.

7.4.6. 定制事件

注意在流程执行的时候生成你自己的定制的事件.事件是唯一的由图元素组合来定义(nodes, 转换transitions,流程定义 process definitions和超状态superstates 是图元素). 在动作里, 你自己的定制代码实现里,或者流程实例执行外部事件里,你可以调用

GraphElement.fireEvent(String eventType, ExecutionContext executionContext);事件类型的名字可自由选择 .

Page 34: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

7.5. 超状态Superstates

超状态是一组节点.超状态可以递归嵌套. 超状态在流程定义中可用做一些层次. 比如,一个应用程序在流程中同步一致聚合所有节

点.动作可同超状态事件关联. 一个结果就是令牌可以在给在给定时间的多个嵌套的节点里.这便于检查是否流程执行,比如说在

start-up阶段. 在jBPM模型, 在超状态你可以自由的聚合任何套的节点.

7.5.1. 超状态转换Superstate transitions

所有转换 leaving a superstate 可以由包含在super state 的节点的令牌产生. 转换能到达超状态. 在这种情况, 令牌将重定向

到在超状态的第一个节点. 从超状态外面的节点直接转换到超状态内的节点. 当然, 另一个方向循环,从超状态内的节点可以转换到

超状态外的节点或者到超状态自身.超状态可以有自引用.

7.5.2. 超状态事件Superstate events

有两个只有超状态才有的事件: superstate-enter 和 superstate-leave .这些事件产生在进入转换节点或离开的时候 . 当令牌在

超状态内开始转换的时候,这些事件不会产生.

注意我们为状态和超状态生成了独立的事件类型. 这让区分的超状态事件和在超状态内传送的节点事件非常容易.

7.5.3. 分级名字Hierarchical names

在节点的范围内,节点名必须是唯一的. 节点的范围是它自己的节点集合node-collection. 节点定义和超状态都是节点集合. 为了

引用超状态的一个节点, 你必须指明相对性用slash (/)分离名字. slash(/) 分离节点名字. 用'..'引用上级. 下一个例子展示如何引

用一个相邻的超状态:

<process-definition> ... <state name="preparation"> <transition to="phase one/invite murphy"/> </state> <super-state name="phase one"> </super-state> ... </process-definition>

下一个例子展示如何到超状态层级

<process-definition> ... <super-state name="phase one"> <state name="preparation"> <transition to="../phase two/invite murphy"/> </node> </super-state> <super-state name="phase two"> </super-state> ... </process-definition>

7.6. 异常处理

jBPM异常处理机制只是应用了java 异常. 图执行它自己不能导致任何问题. 只有它执行委托class能导致异常.

在process-definitions, node s和 transition s, 可指明一个 exception-handler s清单. 每个 exception-handler有一清单动作 .当异常在委托类中发生时候, 当流程元素的父母层搜索匹配到最接近的 exception-handler . 则这个 exception-handler 的动作被

执行.

Page 35: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

注意:jBPM 的异常机制不是完全同java 异常处理相似.在Java,异常可以影响控制流. 而在jBPM, 控制流不能被jBPM 异常处理机

制改变的.异常是要么捕捉要么不捕捉. 不捕捉异常 are被扔给client端(比如 client 端调用 token.signal() )或者异常被 jBPM exception-handler捕捉 .捕捉异常,图执行继续执行好象没有异常发生.

注意:在动作action里处理异常, 通过调用Token.setNode(Node node)把令牌放入图中任意节点是可能的.

7.7. 流程组成Process composition

流程组成在jBPM被支持意味着 process-state .流程状态是同另外流程定义有联系的状态 .当图执行到达流程状态,sub-process的流程实例被建立并且他是同到达的流程状态的执行路线相关联. 超级流程的执行路线将会等待直到子流程实例结束. 当子流程实

例结束是,超级流程的执行路线将离开流程状态继续在超级流程里图执行.

<process-definition name="hire"> <start-state> <transition to="initial interview" /> </start-state> <process-state name="initial interview"> <sub-process name="interview" /> <variable name="a" access="read,write" mapped-name="aa" /> <variable name="b" access="read" mapped-name="bb" /> <transition to="..." /> </process-state> ... </process-definition>

这个'hire' 流程包含 process-state, 跨越了子流程'interview'. 当执行到达'first interview',一个新的执行(= 流程实例)来自最

后版本的'interview' 流程被建立. 然后变量'a' 从hire流程被复制到变量interview 流程里的'aa'. 同样的方式, hire 变量 'b'也被复制到interview变量'bb'. 当interview流程完成, 只有interview流程里的变量 'aa' 被复制回了hire流程的变量a.

一般来说, 当子流程开始时, 所有 variables 有 read 访问属性的从超级流程被读出来并添入新建立的子流程,在离开start start产生信号之前. 当子流程实例完成是,所有 variable s有 write 属性的将从子流程复制会超级流程 . 变量的 mapped-name 元素

允许你指明子流程中使用的变量名字.

7.8. 定制节点行为 Custom node behaviour

在jBPM, 写你自己定制的节点. 为了建立定制节点,必须写一个ActionHandler的实现 . 实现可以执行任何业务逻辑,当也有责任

来传播图的执行.让我们看一个执行更新ERP-system的例子.我们从ERP-system读一个数量,增加数量然后保存进流程变量并且

把结果保存会ERP-system. 基于数量的大小, 我们来通过'small amounts'或 'large amounts' 转换来离开节点.

Figure 7.3. 更新ERP的流程小片段

public class AmountUpdate implements ActionHandler { public void execute(ExecutionContext ctx) throws Exception { // business logic Float erpAmount = ...get amount from erp-system...; Float processAmount = (Float) ctx.getContextInstance().getVariable("amount"); float result = erpAmount.floatValue() + processAmount.floatValue(); ...update erp-system with the result...; // graph execution propagation if (result > 5000) { ctx.leaveNode(ctx, "big amounts"); } else { ctx.leaveNode(ctx, "small amounts"); }

Page 36: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

} }

另外一种方法也是可能的在定制的节点实现中建立一个join令牌 . 举例说明怎样来做这个, 可以检查Fork 和 Join 节点实现的

jbpm源代码 :-).

7.9. 图执行 Graph execution

jBPM图执行模型是基于解释流程定义和 命令链设计模式(chain of command pattern).

解释流程定义意思是把流程定义数据保存在数据库中.在运行时间流程定义信息在流程执行期间被使用 所关注的是:我们用

hibernate's 二级缓存避免在运行时见才载入有关定义信息 由于流程定义不会改变 (参看流程版本) hibernate 缓存流程定义在

内存中.

命令链设计模式意思是图中每个节点有责任传播节点执行.如果节点不传播执行,它就作为一个等待状态.

这个想法是在流程实例开始执行知道它进入等待状态.

令牌表示一个执行路线. 令牌有一个指针指向流程图中的节点.在等待状态期间,令牌能被永久化到数据库里. 现在来仔细看看计算

令牌执行的算法.当信号送到令牌时执行开始. 执行通过命令链设计模式被传送到转换和节点. 这是类图中相关的方法.

Figure 7.4. 图相关的方法

当令牌在节点里的时候,信号能被送到令牌. 发送一个信号就是一个开始执行的指令.一个信号因此必须指明一个令牌当前节点的离

开转换(leaving transition).第一个转换是默认的.当一个信号到令牌,令牌获得它的当前节点然后调用 Node.leave(ExecutionContext,Transition) 方法. 考虑 ExecutionContext作为一个令牌 因为ExecutionContext的主要对象是一个令牌. The Node.leave(ExecutionContext,Transition)方法产生一个 node-leave 事件并且调用 Transition.take(ExecutionContext) . 这个方法产生转换( transition)事件并且在转换目标节点上调用 Node.enter(ExecutionContext) . 这个方法将产生 node-enter事件并且调用 Node.execute(ExecutionContext) .每个类型的节点在excute方法里有它自己的 行为.每个节点的传播图执行的责

任是通过再次调用 Node.leave(ExecutionContext,Transition) 来实现.

总结:

Token.signal(Transition) --> Node.leave(ExecutionContext,Transition) --> Transition.take(ExecutionContext) --> Node.enter(ExecutionContext) --> Node.execute(ExecutionContext)

注意完成下一个状态的计算,包括调用动作(action)是在在client线程完成的.一个常见的误解是所有的计算 *必须*在client线程里

完成.作为任何异步调用 你可以用异步消息(JMS)来完成这个.当消息在同一个事务里被送出的时候同时流程实例更新,必须小心所

有的同步问题.一些工作流系统在图中的所有节点之间用异步消息 .但是在高流量环境里,这个算法给业务流程性能调整更多控制和

灵活性 .

前一页 Up 后一页

第六章 永久化 Home 第八章 上下文

Page 37: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第八章 上下文

上下文同流程变量有关.流程变量是同流程实例相关的key-value对 维护信息. 因为上下文必须保存在数据库中,将会稍微约束使

用.

8.1. 存取变量

org.jbpm.context.exe.ContextInstance 作为提供流程变量服务的中央接口. 你可以从ProcessInstance 获得

ContextInstance:

ProcessInstance processInstance = ...; ContextInstance contextInstance = (ContextInstance) processInstance.getInstance(ContextInstance.class);

最基本操作是

void ContextInstance.setVariable(String variableName, Object value); void ContextInstance.setVariable(String variableName, Object value, Token token); Object ContextInstance.getVariable(String variableName); Object ContextInstance.getVariable(String variableName, Token token);

变量名字是java.lang.String. By default, jBPM 支持下列变量类型:

java.lang.String java.lang.Boolean java.lang.Character java.lang.Float java.lang.Double java.lang.Long java.lang.Byte java.lang.Short java.lang.Integer java.util.Date byte[] java.io.Serializable classes that are persistable with hibernate

要配置jBPM 保存hibernate 永久化对象到变量里,参看保存hibernate永久化对象.

8.2. 变量的生命周期

变量必须在流程档案里声明.在运行时间,你可以把任何java object放到变量里. 如果一个变量不存在,将会被建立.同传统的

java.util.Map一样.

变量可被删除

ContextInstance.deleteVariable(String variableName); ContextInstance.deleteVariable(String variableName, Token token);

已知不足: 类型自动转换目前不支持. 这表明不允许用不同类型的值来覆盖变量. 要想这样做,必须首先删除老变量.当然用同类型

的值覆盖是允许的.

8.3. 变量永久化 Variable persistence

< p> 变量是流程实例的一部分. 保存流程实例到数据库,保持数据库同流程实例同步.作为保存或更新流程变量在数据库中的结果

变量从数据库被建立 ,更新和删除 .更多信息,参看 第六章,永久化.

第八章 上下文

前一页 后一页

Page 38: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

8.4. 变量范围Variables scopes

每个执行路线(参看: 令牌) 有它自己的一套流程变量. 变量请求总是在令牌上发生. 流程实例有令牌树 (参看 面向图的程序设

计 ). 当请求一个变量没有指明令牌, 那么默认的令牌是根令牌.

变量查询递归到给定令牌的父母令牌. 这个行为同程序开发语言里的变量范围是相似的.

当在令牌上设置不存在变量,那么变量就在根令牌root-token上被建立 .这就是说每个变量默认就是整个流程范围. 如果想建立一

个令牌的局部变量,必须显式的使用API:

ContextInstance.createVariable(String variableName, Token token);

8.4.1. 变量重载 Variables overloading

变量重载意味着意味着每个执行路线都有自己的同名字的变量复制. 它们被当作无关的和不同类型的. 当你在一个转换里调用多个

并发的执行路线的时候,变量重载将变得有趣 这时候区分这些执行路线只能通过它们的一组变量.

8.4.2. 变量重写 Variables overriding

变量重写是说在嵌套中的执行路线里的变量的值将覆盖更高层中执行路线中变量的值. 一般的,嵌套执行路线涉及到并发问题: 在form和join之间的执行路线是到达fork的执行路线的. 比如,如果你有变量'contact'在流程实例范围, 你可以在嵌套的执行路

线'shipping'和'billing'重写这个变量.

8.5. 临时变量 Transient variables

当流程实例永久化到数据库中,正常变量也作为流程实例的一部分被永久化了.某些状态下你可能想在委托类里用变量 , 但是你不

想把它储存在数据库中. 比如一个数据库connection 从jBPM传送到外面的一个委托类.这就可以由临时变量来做.

临时变量的生命周期同ProcessInstance java object一样.

由于这个自然特性,临时变量同令牌无关. 因此只有一个流程实例object的临时变量的map.

临时变量在上下文实例中可以从它们自己的变量组访问, 不需要在processdefinition.xml中声明

Object ContextInstance.getTransientVariable(String name); void ContextInstance.setTransientVariable(String name, Object value);

8.6. 定制变量永久化 Customizing variable persistence

变量保存在数据库中有两个步骤:

user-java-object <---> converter <---> variable instance

变量保存在 VariableInstance s. VariableInstance s 的成员被被hibernate映射到数据库的字段. 在jBPM默认的配置中, 6 类型

的VariableInstances被使用:

DateInstance (是一个java.lang.Date field 被映射到 Types.TIMESTAMP in the database)

DoubleInstance (是一个java.lang.Double 被映射到 a Types.DOUBLE in the database)

StringInstance (是一个java.lang.String 被映射到 Types.VARCHAR in the database)

LongInstance (是一个java.lang.Long field 被映射到 Types.BIGINT in the database)

HibernateLongInstance (hibernatable types作为long id field.一个java.lang.Object 被映射作为一个引用到 hibernate 数

Page 39: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

据库中的实体)

HibernateStringInstance (hibernatable types 作为 string id field. 一个java.lang.Object 被映射作为一个引用到

hibernate 数据库中的实体)

转换器用来在java-user-objects 和保存在VariableInstance s的java objects 来转换. 因此当一个流程变量被设置为

ContextInstance.setVariable(String variableName, Object value) , 变量可选则被改变然后改变的对象被保存在

VariableInstance . 转变器是实现了以下接口:

public interface Converter extends Serializable { boolean supports(Class clazz); Object convert(Object o); Object revert(Object o); }

转变器是可选的. 转变器必须被 jBPM 类载入器可用

user-java-objects 被转换并保存在变量实例的方法在 org/jbpm/context/exe/jbpm.varmapping.properties文件中配置 . 定制

这个属性文件, 把修改后的版本放到classpath的根, 说明在 章节 5.2, “配置文件” 属性文件每行都指明2或3个类名有空格搁开: the user-java-object的类名,可选的转变器的类名和变量实例的名字.当你引用你定制的转变器, 确定他们在 jBPM class path . 当你引用你定制的变量实例, 他们必须在 jBPM class path 并且hibernate 映射文件

org/jbpm/context/exe/VariableInstance.hbm.xml 必须更新以包含定制的 VariableInstance的子类.

比如, 看文件 org/jbpm/context/exe/jbpm.varmapping.properties.

java.lang.Boolean org.jbpm.context.exe.converter.BooleanToStringConverter org.jbpm.context.exe.variableinst

这行指明了所有类型为Boolean的类型被转换器 BooleanToStringConverter转换并且 结果对象(a String)将被保存在

StringInstance中.

如果没有转变器

java.lang.Long org.jbpm.context.exe.variableinstance.LongInstance

表明Long objects被存储在变量实例LongInstance不需要任何改变.

前一页 Up 后一页

第七章 流程建模 Home 第九章 任务管理

Page 40: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第九章 任务管理

BPM核心业务是能够永久化流程执行. 对任务管理和个人的任务清单来说这个特性是非常有用的. jBPM 允许指明一段软件描述所

有人的任务中处于等待状态的流程.

9.1. 任务

任务是流程定义的部分并且定义在流程执行时间任务实例怎样生成和分配.

任务可以在process-definition中 用 task-node s定义. 常用的方式是用一个task-node定义一个或多个任务. 这种情况下

task-node 代表一个由用户完成的任务并且流程执行将一直等待知道参与者完成这个任务. 当参与者完成任务,流程执行将继续.当多个任务在 task-node被指定 , 默认的行为是等待所有的任务被完成.

任务也可以在 process-definition被指定 . 任务在流程定义中指定可以通过名字查找(lookup)并且可以在 task-nodes里被引用

(referenced)后者在动作里被使用(used) . 事实上, 所有任务 (在task-nodes里也是) 可以通过给一个名字在流程定义中查找

到.

任务名字必须是唯一的在整个流程定义中. 任务可以给优先级别. 这个优先级别将用做初始化每个任务实例建立时的优先级. TaskInstances可以在以后修改这个优先级别.

9.2. 任务实例

任务实例可以被分配给一个actorId (java.lang.String). 所有任务实例被保存在数据库中的一张表中

(JBPM_TASKINSTANCE).可以通过给定的actorId查询这个表得到所有的任务实例, 将会得到特定用户的任务清单.

jBPM 任务清单机制可以组合jBPM tasks 和其他任务, 甚至当这些任务同流程执行不相关. 这样jBPM 开发者可以容易组合

jBPM-process-tasks 和其他在一个集中task-list-repository的应用程序的任务.

9.2.1. 任务实例生命周期

任务实例生命周期是直接了当的: 在建立后, 任务实例可以随意的被开始. 然后,任务实例可以被结束,意思是任务实例被标记为完

成了.

为了灵活性,分派不是生命周期的一部分.因此任务实例可能被分配也可能不被分配.任务实例分配不影响任务实例的生命周期.

任务实例的建立典型的是由流程执行进入一个 task-node (通过方法 TaskMgmtInstance.createTaskInstance(...)). 然后, 一个

用户接口组件将用TaskMgmtSession.findTaskInstancesByActorId(...) 查询数据库得到任务清单tasklists.然后, 在收集了

用户的输入后,UI组件调用 TaskInstance.assign(String), TaskInstance.start() 或 TaskInstance.end(...).

任务实例通过date-properties维护它的状态包括: create, start和 end. 这些属性可以通过TaskInstance它们对应的getters方法.

当前,完成的任务实例被标记为end date 所以它们不能被随后的任务列表查询获得.但它们依然保存在 JBPM_TASKINSTANCE表里.

9.2.2. 任务实例和图执行

任务实例是在参与者tasklist的项目. 任务实例可作为信令(发射信号).一个信令任务实例就是一个任务实例在完成的时候可以发送

一个信号给它的令牌去继续流程执行. 任务实例可以被阻塞,意思是说相关的令牌(= 执行路线)不允许离开 task-node,在任务实

例被完成之前.默认的任务实例是信令(signalling )和非阻塞的(non-blocking).

在多个任务同一个task-node关联情况下,流程开发者可以指定怎样完成任务实例来影响流程的继续 . 下面是一个给task-node的singal-property的值的清单.

last : 这是默认的. 当last实例被完成时候获得执行. 当在这个入口没有任务被生成时候,执行继续.

第九章 任务管理

前一页 后一页

Page 41: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

last-wait : 当last实例被完成时候获得执行. 当这个节点入口没有任务被建立时,任务节点执行等待直到任务被建立. first : 当first实例被完成时候获得执行. 当在这个入口没有任务被生成时候,执行继续. first-wait : 当first实例被完成时候获得执行. 当在这个入口没有任务被生成时候,执行继续. last-wait: 当first实例被完成时候获得执行. 当这个节点入口没有任务被建立时,任务节点执行等待直到任务被建立. unsynchronized : 执行一直继续,不管任务是否没建立或依然没有完成. never : 执行永远不继续, 不管任务是否建立或依然没有完成.

任务实例建立必须基于以上运行时间计算. 这种情况下,增加一个 ActionHandler 在task-node的 node-enter事件里 并且设置属

性 create-tasks="false" . 下面是一个动作handler的实现:

public class CreateTasks implements ActionHandler { public void execute(ExecutionContext executionContext) throws Exception { Token token = executionContext.getToken(); TaskMgmtInstance tmi = executionContext.getTaskMgmtInstance(); TaskNode taskNode = (TaskNode) executionContext.getNode(); Task changeNappy = taskNode.getTask("change nappy"); // now, 2 task instances are created for the same task. tmi.createTaskInstance(changeNappy, token); tmi.createTaskInstance(changeNappy, token); } }

如例子所展示,在task-node指定的任务被建立. 它们也可以在 process-definition指定并且通过 TaskMgmtDefinition来获取. TaskMgmtDefinition用任务管理信息 扩展(extends) ProcessDefinition .

标记任务实例的API完成用 TaskInstance.end() .随意地,你可以指定一个转换在end 方法里. 这种情况下这个任务实例完成将出

发执行的继续,task-node 通过指定的转换离开..

9.3. 分配

流程定义包含任务节点. task-node包含0或多个任务 .任务是流程定义的静态描述部分. 在运行时间, 任务导致任务实例的建立.一个任务实例对应着个人任务列表里的一个入口.

在jBPM, 推 和 拉l 模式 (看下面) 的任务分派可以组合使用. 流程能计算任务的责任并把它"推"到他/她的任务清单里(tasklist).或者另外的方法, 把任务分配给参与者池, 这种情况下池中的每一个参与者可以"拉"任务并且把它们放到参与者个人的任务清单中

(tasklist).

9.3.1. 分配接口

通过接口AssignmentHandler来分配任务实例:

public interface AssignmentHandler extends Serializable { void assign( Assignable assignable, ExecutionContext executionContext ); }

一个分配handler实现在任务实例建立的时候被调用. 在这个时候,任务实例可以分配给一个或多个参与者. AssignmentHandler 实现可以调用 Assignable 方法(setActorId或 setPooledActors )来分配任务. 可分配的要么是一个 TaskInstance 或者

SwimlaneInstance (= 流程角色).

public interface Assignable { public void setActorId(String actorId); public void setPooledActors(String[] pooledActors); }

TaskInstances 和 SwimlaneInstance s 两者都可以分配给指定的用户或参与者池. 分配一个TaskInstance给用户, 调用

Assignable.setActorId(String actorId) . 分配一个TaskInstance给候选参与者池, 调用 Assignable.setPooledActors(String[] actorIds).

流程中的每个任务都可以用在运行时间执行分配handler的实现关联起来.

Page 42: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

当流程中多个任务被分配给同一个人或一组参与者,考虑 swimlane用途

允许建立重用的 AssignmentHandler s,每个 AssignmentHandler的用途可以在 processdefinition.xml配置. 参看 章节 13.2, “代理” 更多有关怎么添加分配handler的信息.

9.3.2. 分配数据模型

管理分配任务实例和分配swimlance实例到参与者的数据模型如下. 每个 TaskInstance 有actorId和一组被缓存的参与者.

Figure 9.1. 分配模型类图

actorId对任务负责, 当一组缓存的参与者代表候选者集合,如果他们得到任务就可以负责.actorId 和pooledActors 可以任意的

组合.

9.3.3. 推模式

任务实例的actorId 表明对指定任务责任的. TaskInstance 缓存的参与者是任务参与者的候选人. 典型的,TaskInstance 的actorId将引用一个一个用户. 缓存的参与者可以引用用户和组.

个人任务清单是所有所有指定actorId作为用户的 TaskInstance s.这个清单的获得是用过 TaskMgmtSession.findTaskInstances(String actorId).

9.3.4. 拉模型

另外一面, 共有的任务用来给从 共有的参与者中引用的用户. 获取集中的任务典型两个步骤操作: 1)从身份组件得到给定用户所

有的组2)根据用户的actorId和从用户组得到的actorId来得到所有共有的任务.得到给定用户的所有共有的任务的清单通过方法

TaskMgmtSession.findPooledTaskInstances(String actorId) 或 TaskMgmtSession.findPooledTaskInstances(List actorIds) . 这些方法只返回任务实例的actorId是null或给定actorId之一匹配共有的的参与者其中一个.

为了防止多个用户在同一个共有的任务上工作, 更新TaskInstance 为用户的actorId就可以了. 做了这个, 任务实例将不会显示

在共有的任务清单里,但只在用户的个人任务清单里. 设置TaskInstance 的actorId 为null,将会把任务实例放回共有的任务里.

9.4. 泳道

泳道(swimlane)是流程角色.这是用来指明在一个流程中要完成多个任务中的同一个参与者的机制. 在第一个任务实例为给定的

swimlane建立后,参与者将被同一个流程里所有随后都处于同一个swimlane中的任务记住.swimlane 因此有一个 分派 并且所

有引用一个swimlane的任务将不会指定一个 分配.

当给定swimlane第一个任务建立时,swimlane 的 AssignmentHandler 被调用. Assignable 传递到 AssignmentHandler 将会成

为 SwimlaneInstance . 需要知道的重点是所有分派是在给定swimlane任务实例上完成.将传播到swimlane实例.这个行为被实

现作为默认的,因为个人将作为必要的流程角色履行任务.因此所有以后的任务实例分派到swimlane完成,自动到哪个用户.

Swimlane 是从UML活动图中借来的术语.

Page 43: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

9.5. 任务事件

任务有动作关联. 有4个标准任务事件类型定义: task-create, task-assign, task-start 和 task-end.

task-create 在任务实例建立的时候被产生.

task-assign 当任务实例被分配的时候产生.注意当这个事件是动作被执行,你可以访问前一个参与者通过

executionContext.getTaskInstance().getPreviousActorId()

task-start 是当 TaskInstance.start()被调用时产生 . This can be used to indicate that the user is actually starting to work on this task instance. Starting a task is optional.

task-end 当 TaskInstance.end(...)被调用时产生 .这标记着任务的完成. 如果任务是相关于流程执行, 这个调用将出发流程执行

继续.

因此任务可以有事件和动作, 异常handlers也可以对任务指定.更多关于异常处理的信息参看 章节7.6, “异常处理”.

9.6. 任务定时器

在节点上,定时器可以指定在任务上 参看 章节10.1, “定时器”.

关于任务定时器指明的事情是 cancel-event 可以定制的.默认的, 任务上的定时器在任务结束时,将被放弃 (= 完成). 但在定时器

的 cancel-event 属性, 流程开发人员能定制比如 task-assign 和 task-start . cancel-event支持多个事件. cancel-event 类型

能被用逗号分隔的多个事件列表.

9.7. 任务控制器

任务是用来收集用户输入的.但目前有许多用户接口可被用来用户的任务. 比如. 一个web应用程序, swing应用程序,及时消

息,Email表单,... 因此任务控制器在流程变量(= process context) 和用户接口应用程序之间起到了桥的作用. 任务控制器为用

户接口应用程序提供流程变量的视图.

任务控制器有2个责任:第一个, 从流程变量里提取信息. 从流程变量里提取的信息表示作为一个指定的参数的集合.参数用做来自

用户接口表单的输入. 第二个责任是保存用户提交的参数到流程变量里.

Figure 9.2. 任务控制器

在这个场景里, 这是流程变量和表单参数之间一对一的影射.这种情况,默认的jBPM任务控制器可以使用. 任务控制器在task元素

中指定.

Page 44: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

<task name="clean ceiling"> <controller> <variable name="a" access="read" mapped-name="x" /> <variable name="b" access="read,write,required" mapped-name="y" /> <variable name="c" access="read,write" /> </controller> </task>

name 属性引用流程变量的. access 属性指明变量是否readable, writable and 或 required. 这个信息可以用于用户接口来产

生正确的表单控制. access 属性是任意的并且默认 access 是 read,write .mapped-name 是任意的并且表示用户接口的标签用

于表示一个参数.

task-node 能有多个任务并且 start-state 能有1个任务.

如果一个简单的一对一映射在流程变量和表单参数太约束,你可以写你自己的 TaskControllerHandler 实现. TaskControllerHandler接口:

public interface TaskControllerHandler extends Serializable { List getTaskFormParameters(TaskInstance taskInstance); void submitParameters(Map parameters, TaskInstance taskInstance); }

这里是在一个任务里如何配置你自己定制的任务控制器实现:

<task name="clean ceiling"> <controller class="com.yourcom.CleanCeilingTaskControllerHandler"> -- here goes your task controller handler configuration -- </controller> </task>

9.8. 定制任务实例

Task instances can be customized. The easiest way to do this is to create a subclass of TaskInstance. Then update the property jbpm.task.instance.class and specify the class name of your custom class that inherits from TaskInstance. Also create a hibernate mapping file for the subclass (using the hibernate extends="org.jbpm.taskmgmt.exe.TaskInstance"). Then add that mapping file to the list of mapping files in the hibernate.cfg.xml

9.9. 身份组件

用户管理,组和权限管理一般都称做身份管理. jBPM 包括可选的身份组件,可以弄你公司自己的身份存储数据来代替.

jBPM 身份管理组件包括组织知识模型. 任务分配典型的根据组织知识来完成. 因此这个隐含的组织知识模型,描述了用户,组,系统

和它们之间的关系. 任意的,权限和角色也可以包含在组织模型中.数个学术研究尝试失败,证明没有通用的组织模型可以用来适合

所有的组织.

jBPM 处理的方法是定义参与者作为实际的流程的实际参与者. 一个参与者用它的ID叫做actorId来标识. jBPM 只有关于actorId的知识并且为了灵活性他们表示为 java.lang.String s . 因此任何关于组织模型和数据结构的知识都不在jBPM 核心引擎之内.

作为扩充jBPM我们会提供(in the future)组件来管理简单的用户-角色模型. 这个用户和角色之间多对多的关系同J2EE和servlet规范中定义的一致因此他能作为一个新的开发开始点 .可以检查jbpm jira问题来追踪更多的细节.

注意用户-角色模型用在servlet,ejb和portlet规范里,是不足以处理任务分派. 在用户和角色之间模型是多对多关系.这不包含任何

关于team以及组织结构用户如何涉及流程的的信息.

9.9.1. 身份模型

Page 45: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Figure 9.3. 身份模型类图

黄色类图是有关类表达下一节讨论的分配handlerre.

用户表示用户或服务. Group是任何一种类型的一群用户 .组能嵌套进team之间,业务单位之间和整个公司的关系模型 . 组有类

型来区分组层次,比如头发颜色组. Membership s 表示多对多的在用户和组之间.membership可用来表示在公司中的职位. 成员

的名字可以用来指明用户在组里履行的角色.

9.9.2. 分配表示

身份组件是在分派任务期间评估计算参与者的表达式的时候需要. 这里有个例子在流程定义中用分派表达:

<process-definition> ... <task-node name='a'> <task name='laundry'> <assignment expression='previous --> group(hierarchy) --> member(boss)' /> </task> <transition to='b' /> </task-node> ...

分配语法表达如下:

first-term --> next-term --> next-term --> ... --> next-term where first-term ::= previous | swimlane(swimlane-name) | variable(variable-name) | user(user-name) | group(group-name) and next-term ::= group(group-type) | member(role-name)

9.9.2.1. 第一术语first-term

表达式分析是从左向右. first-term 指明了在身份模型中的用户或组. 以后的术语从中间的用户或组来计算下一个术语.

Page 46: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

previous 意思是任务被分派给当前已经验证过的参与者.这意味着参与者在流程中执行前一个步骤.

swimlane(swimlane-name) 意思是用户或组从指明的swimlane instance取走.

variable(variable-name) 意思是用户或组从指明的variable instance取出. variable instance包含 java.lang.String,用户或组

从身份组件中获得. 或者variable instance 包含用户或组对象.

user(user-name) 意思是用户是从身份组件里取出.

group(group-name)意思是组是从身份组件里取出的 .

9.9.2.2. 下一个术语 Next terms

组(group-type) 得到用户的组. 意思是 前一个术语(previous terms)得到用户. 它根据给定的group-type搜索组在所有的用户

成员里.

member(role-name) 从组里得到用户执行的给定角色.前一个术语(previous terms) 必须有一个组结果.搜索所有用户有成员在

指定组里它的成员名字匹配给定的角色名.

9.9.3. 删除身份组件 Removing the identity component

当你想用你们公司组织自己的数据源比如公司用户数据库或LDAP系统,你可以拔除jBPM身份组件. 你需要做的唯一事情就是删除

行 ...

<mapping resource="org/jbpm/identity/User.hbm.xml"/> <mapping resource="org/jbpm/identity/Group.hbm.xml"/> <mapping resource="org/jbpm/identity/Membership.hbm.xml"/>

从文件 hibernate.cfg.xml

ExpressionAssignmentHandler 依赖身份组件因此你不将不能用它. 这中情况下你想重用 ExpressionAssignmentHandler并且同

你的用户数据绑定 ,你可以扩展 ExpressionAssignmentHandler然后重写 getExpressionSession方法.

protected ExpressionSession getExpressionSession(AssignmentContext assignmentContext);

前一页 Up 后一页

第八章 上下文 Home 第十章 调度程序

Page 47: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第十章 调度程序

在jBPM如何是定时器工作.

在流程事件之上,定时器能被建立. 当定时器失效, 动作被执行或转换发生.

10.1. 定时器 Timers

最容易的方法指定一个定时器是在节点里加入定时器元素.

<state name='catch crooks'> <timer name='reminder' duedate='3 business hours' repeat='10 business minutes' transition='time-out-transition' > <action class='the-remainder-action-class-name' /> </timer> </state>

定时器可以在节点上指定, 在节点离开后不执行. 转换和动作两个都是任意的. 当定时器计时器开始执行时,下列时间顺序发生:

一个timer类型的事件产生 如果指定了动作,则动作被执行. 如果转换被指定,转换会送出一个信号继续执行.

每个定时器必须有唯一的名字.如果没有给定时器元素指定名字 ,节点的名字被作为定时器的名字.

定时器动作可作为任何被支持的动作元素比如动作或脚本.

定时器由动作建立或放弃.2个action-elements : create-timer和 cancel-timer . 实际上, 这两个定时器元素只是一个短的符号

create-timer动作在 node-enter 和 cancel-timer动作在 node-leave.

10.2. 调度程序发布

流程执行建立或放弃定时器. 定时器存放在一个定时器储存里. 一个隔离的定时器运行器必须检查定时器储存并且在合适的时候执

行定时器.

第十章 调度程序

前一页 后一页

Page 48: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Figure 10.1. 调度程序组件一览

下列类图说明了涉及到调度程序发布的类. 接口 SchedulerService和 TimerExecutor被指定使定时器执行的机制是可插入的 .

Figure 10.2. 调度程序类一览

前一页 Up 后一页

第九章 任务管理 Home 第11章.业务日历

Page 49: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第11章 业务日历

本章描述业务jBPM的业务日历. 业务日历是关于业务小时用于计算任务和定时期预期时间的.

业务日历也能用于计算日期的增加.

11.1. 持续时间

持续时间指明绝对的业务小时.语法如下:

<quantity> [business] <unit>

这里 <quantity> 是可被Double.parseDouble(quantity)解析的. <unit> 是其中之一{second, seconds, minute, minutes, hour, hours, day, days, week, weeks, month, months, year, years}. 加上任意指示 business 意味着这个持

续时间的业务小时. 没有指示符 business , 持续时间被解释为绝对的时间间隔.

11.2. 配置

文件 org/jbpm/calendar/jbpm.business.calendar.properties 指明业务时间 .配置文件可被定制并且修改copy可以放在

classpath的根.

这是一个业务小时规范 jbpm.business.calendar.properties:

hour.format=HH:mm #weekday ::= [<daypart> [& <daypart>]*] #daypart ::= <start-hour>-<to-hour> #start-hour and to-hour must be in the hour.format #dayparts have to be ordered weekday.monday= 9:00-12:00 & 12:30-17:00 weekday.thuesday= 9:00-12:00 & 12:30-17:00 weekday.wednesday= 9:00-12:00 & 12:30-17:00 weekday.thursday= 9:00-12:00 & 12:30-17:00 weekday.friday= 9:00-12:00 & 12:30-17:00 weekday.saturday= weekday.sunday= day.format=dd/MM/yyyy # holiday syntax: <holiday> # holiday period syntax: <start-day>-<end-day> # below are the belgian official holidays holiday.1= 01/01/2005 # nieuwjaar holiday.2= 27/3/2005 # pasen holiday.3= 28/3/2005 # paasmaandag holiday.4= 1/5/2005 # feest van de arbeid holiday.5= 5/5/2005 # hemelvaart holiday.6= 15/5/2005 # pinksteren holiday.7= 16/5/2005 # pinkstermaandag holiday.8= 21/7/2005 # my birthday holiday.9= 15/8/2005 # moederkesdag holiday.10= 1/11/2005 # allerheiligen holiday.11= 11/11/2005 # wapenstilstand holiday.12= 25/12/2005 # kerstmis business.day.expressed.in.hours= 8 business.week.expressed.in.hours= 40 business.month.expressed.in.business.days= 21 business.year.expressed.in.business.days= 220

第11章 业务日历

前一页 后一页

Page 50: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

前一页 Up 后一页

第十章 调度程序 Home 第12帐 记录

Page 51: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第12章. 记录

日志的目的是为了追踪流程执行的历史.作为流程执行运行时间数据,所有的增量数据都会保存在日志里 .

流程日志不要同软件的日志混淆. 软件日志是追踪软件程序的执行(通常是用于调试目的).流程日志跟踪流程实例的执行.

有几个关于流程日志信息的use case. 明显的就是咨询特定流程执行的历史.

另外一个use case 是业务活动监视(BAM). BAM将查询和分析流程执行的日志来发现有用的关于业务流程的统计信息 .比如. 流程每个步骤平均花费了多少时间? 流程的瓶径在那里? 在一个组织里这个信息是执行业务流程管理的关键. 真实业务流程管理是关

于组织怎样管理它们的流程, 怎样支持信息技术*和*怎么改善迭代过程.

下一个use case 是取消还原(undo)功能. 流程日志能用来执行取消还原(undo).取消还原由于日志包括增量的运行时间信息,日志能够按照相反的顺序把流程带回到以前的状态.

12.1. 建立一个日志

jBPM组件当运行流程执行的时候产生日志 .用户也能插入流程日志. 日志入口是一个来自继承

org.jbpm.logging.log.ProcessLog的 java objec. 流程日志入口被加到 LoggingInstance . LoggingInstance 扩展

ProcessInstance.

jBPM产生几种日志: 图执行日志,上下文日志和任务管理日志.更多有关这些日志的信息,可以参考javadocs. 一个好的开始点是类

org.jbpm.logging.log.ProcessLog因为从这个类你可以向下导航到继承树 .

LoggingInstance将集合所有的日志入口 . 当 ProcessInstance被保存 ,所有在 LoggingInstance的日志将刷新到数据库里. ProcessInstance的 logs -field 没有用hiberate映射避免在每个事务里日志从数据库中检索. 每个 ProcessLog有执行路线上下

文( Token)制造 并且 ProcessLog引用令牌 . 令牌被用做index-sequence 生成器为了令牌里的 ProcessLog索引 . 这对日志

检索是重要的. 这个方法,随后的事务里产生的日志产生将有后面的顺序号. .

对发布来说日志是不重要的, 在ProcessDefinition里 去掉额外的 LoggingDefinition是足够的 .阻止 LoggingInstance s 被捕

捉导致日志没有维护.我们以后将增加更加精细颗粒的日志配置控制 . 参看问题 'log 级别配置'.

增加流程日志 API方法如下.

public class LoggingInstance extends ModuleInstance { ... public void addLog(ProcessLog processLog) {...} ... }

UML 日志信息图如下:

第12章. 记录

前一页 后一页

Page 52: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Figure 12.1. jBPM 日志信息类图

CompositeLog 是特殊类别的日志入口 .它用做数个子日志的父母日志, 因此在日志里建立层级结构. 插入日志API如下

public class LoggingInstance extends ModuleInstance { ... public void startCompositeLog(CompositeLog compositeLog) {...} public void endCompositeLog() {...} ... }

CompositeLog s总是调用在 try-finally -block确保层级结构日志是一致的. 比如:

startCompositeLog(new MyCompositeLog()); try { ... } finally { endCompositeLog(); }

12.2. 日志检索Log retrieval

如前所说,日志不能通过LoggingInstance 导航到它的日志来从数据库中检索.替代的流程实例日志总是从数据库中查询. LoggingSession有两个方法用做这个目的 .

第一个方法检索所有流程实例的日志.这些日志将被组织成一个Map. map将关系到ProcessLogs清单用流程实例的所有令牌.清单包含ProcessLogs 同它们建立的顺序一样.

public class LoggingSession { ... public Map findLogsByProcessInstance(long processInstanceId) {...} ... }

第二个方法检索日志是用指定的令牌. 结果列表包括ProcessLogs,同它们建立的顺序一样.

public class LoggingSession { public List findLogsByToken(long tokenId) {...} ... }

Page 53: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

12.3. 数据仓库 Database warehousing

有时,你可能想使用数据库仓库为jBPM日志.数据仓库意思是你建立隔离的数据库为各种不同目的的流程日志.

有很多理由为jBPM 日志使用数据仓库.有时可能从使用的生产数据库产生沉重的查询. 其他状态可能做一些扩展分析. 数据仓库可

以为了优化在一个修改数据库schema上完成.

本章,我们只是推荐了数据仓库技术. 目的是多变的,jBPM里包含的通用解决方案可以覆盖这些需求.

前一页 Up 后一页

第11章 业务日历 Home 第13章jBPM流程定义语言(JPDL)

Page 54: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第13章. jBPM 流程定义语言 (JPDL)

JPDL 是指定的xml模式和机制包装所有的流程定义相关文件到一个流程文档.

13.1. 流程文档

流程文档是一个zip文件. 文档的中心流程是 processdefinition.xml . 文件中主要信息是流程图. processdefinition.xml也包含关于动作和任务的信息 . 流程文档也包含其他流程相关文档比如类,任务ui-form ...

13.1.1. 发布流程文档

发布文档文档可以通过3种方式来做: 用流程设计器工具, 用ant任务或编程实现.

发布任务通过设计器工具依然在开发阶段.

发布任务文档通过ant任务如下:

<target name="deploy.par"> <taskdef name="deploypar" classname="org.jbpm.jpdl.par.ProcessArchiveDeployerTask"> <classpath --make sure the jbpm-[version].jar is in this classpath--/> </taskdef> <deploypar par="build/myprocess.par" /> </target>

一次发布多个流程文件, 用嵌套的fileset元素. file属性是可选的. 其他ant 任务属性是:

cfg : cfg 可选的, 默认值是'hibernate.cfg.xml'. hibernate配置文件包含jdbc connection属性和mapping 文件. properties : 属性是可选的并且覆盖所有来自hibernate.cfg.xml的同样属性 createschema : 如果为true, jbpm数据库模式将在发布之前被建立.

流程文档也可通过编程来发使用类 org.jbpm.jpdl.par.ProcessArchiveDeployer

13.1.2. 流程版本

流程定义基本不会改变,因为预测所有流程定义变化是非常困难的.

围绕这个问题, jBPM 有一个久经考验的流程版本机制.版本机制允许多个同名的流程定义在数据库中同时存在. 流程实例使用 后

的可用版本并且并且在同一个流程里持续执行知道生命周期结束.当较新的版本被发布, 较新的建立实例将用 新的版本,同时老的

流程实例用老的流程定义保持执行.

流程定义是组合声明指定图和一组相关的java classes. Java classes 能被jBPM运行时间环境以2种方式使用: 让这些class被jBPM classloader看到. 这是把你的委托 类放到.jar文件然后到 jbpm-[version].jar . java classes 也能被包括进流程文档. 当你包括你的委托类到流程文档(它们对jbpm classloader是不可见的), jBPM 将使用这些class版本. 关于流程载入的信息参考

13.2章节, “委托”

当流程档案被发布时, 它在jBPM数据库中生成一个流程定义. 流程定义可以被版本化基于基本的流程定义名字.当命名的流程档案

被发布时,发布者将分配给它一个版本数字. 为了分配数字,发布者将查询同名的流程 高版本数字加1.没有名字的流程定义版本数

字为-1.

13.1.3. 过程转换 Process conversion

一个转换class把jBPM 2.0文档转为3.0兼容流程文档.建立一个输出目录来处理被改变的流程文档. 输入下列命令行来构造jBPM 3.0发布:

第13章. jBPM 流程定义语言 (JPDL)

前一页 后一页

Page 55: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

java -jar converter.jar indirectory outdirectory

"indirectory"替换为你的jBPM 2.0文档目录."outdirectory"为输出3.0兼容的目录.

13.2. 委托

委托是一种机制用来在流程执行中包含用户定制代码.

13.2.1. jBPM class loader

jBPM class loader是用来载入 jBPM classes.意思是, classloader有库 jbpm-3.x.jar在它的 classpath. 要想class对jBPM classloader可见必须把它们放在 jbpm-3.x.jar里或者在web应用程序的 WEB-INF/lib

13.2.2. 流程 process class loader

委托类被流程classloader同它们定义一致的流程定义. 流程classLoader以jBPM classLoader为父母 . 流程classLoader增加

了特定流程定义的所有类. 你可以增加类到流程定义只要把它们放在流程档案/class文件夹下. 说明这是唯一有用的当你想版本化

你加在流程定义里的类. 如果版本是不必要的,那么更加有效的方式是把它们放在jBPM class loader.

13.2.3. 委托配置

委托类包含在流程执行里调用的用户代码. 常见的例子是动作. 在动作里的情况, 接口 ActionHandler的实现能在流程事件里被调用.委托在processdefinition.xml里 指明. 3个数据可以用于指定委托的时候:

1) 类名 (必须的) : 全称唯一的委托类名字. 2) 配置类型 (可选) : 指明一个方式来实例和配置委托对象. 默认的配置是默认的构造和配置信息被忽略的. 3) 配置 (可选) : 委托对象被配置类型所要求的格式的配置信息.

下面描述所有的配置类型:

13.2.3.1. config-type field

This is the default configuration type. The config-type field will first instantiate an object of the delegation class and then set values in the fields of the object as specified in the configuration. The configuration is xml, where the elementnames have to correspond with the field names of the class. The content text of the element is put in the corresponding field. If necessary and possible, the content text of the element is converted to the field type.

Supported type conversions:

String doesn't need converting, of course. but it is trimmed. primitive types such as int, long, float, double, ... and the basic wrapper classes for the primitive types. lists, sets and collections. in that case each element of the xml-content is consitered as an element of the collection and is parsed, recursively applying the conversions. if the type of the elements is different from java.lang.String this can be indicated by specifying a type attribute with the fully qualified type name. maps. in this case, each element of the field-element is expected to have one subelement key and one element value. The key and element are both parsed using the conversion rules recursively. Just the same as with collections, a conversion to java.lang.String is assumed if no type attribute is specified. org.dom4j.Element for any other type, the string constructor is used.

For example in the following class...

public class MyAction implements ActionHandler { // access specifiers can be private, default, protected or public private String city; Integer rounds; ... }

Page 56: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

...this is a valid configuration:

... <action class="org.test.MyAction"> <city>Atlanta</city> <rounds>5</rounds> </action> ...

13.2.3.2. config-type bean

Same as config-type field but then the properties are set via setter methods, rather then directly on the fields. The same conversions are applied.

13.2.3.3. config-type constructor

This instantiator will take the complete contents of the delegation xml element and passes this as text in the delegation class constructor.

13.2.3.4. config-type configuration-property

First, the default constructor is used, then this instantiator will take the complete contents of the delegation xml element, and pass it as text in method void configure(String);. (as in jBPM 2)

13.3. JPDL xml schema

The JPDL schema is the schema used in the file processdefinition.xml in the process archive.

13.3.1. process-definition

Table 13.1.

13.3.2. node

Name Type Multiplicity Description

name attribute optional the name of the process

swimlane element [0..*]the swimlanes used in this process. the swimlanes represent process roles and they are used for task assignments.

start-state element [0..1]the start state of the process. Note that a process without a start-state is valid, but cannot be executed.

{end-state|state|node|task-node|process-state|super-state|fork|join|decision}

element [0..*]the nodes of the process definition. Note that a process without nodes is valid, but cannot be executed.

event element [0..*]the process events that serve as a container for actions

{action|script|create-timer|cancel-timer}

element [0..*]

global defined actions that can be referenced from events and transitions. Note that these actions must specify a name in order to be referenced.

task element [0..*]global defined tasks that can be used in e.g. actions.

exception-handler element [0..*]a list of exception handlers that applies to all exceptions thrown by delegation classes thrown in this process definition.

Page 57: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Table 13.2.

13.3.3. common node elements

Table 13.3.

13.3.4. start-state

Table 13.4.

13.3.5. end-state

Table 13.5.

13.3.6. state

Table 13.6.

13.3.7. task-node

Name Type Multiplicity Description

{action|script|create-timer|cancel-timer}

element 1a custom action that represents the behaviour for this node

common node elements See common node elements

Name Type Multiplicity Description

name attribute required the name of the node

transition element [0..*]

the leaving transitions. Each transition leaving a node *must* have a distinct name. A maximum of one of the leaving transitions is allowed to have no name. The first transition that is specifed is called the default transition. The default transition is taken when the node is left without specifying a transition.

event element [0..*] supported event types: {node-enter|node-leave}

exception-handler

element [0..*]a list of exception handlers that applies to all exceptions thrown by delegation classes thrown in this process node.

timer element [0..*] specifies a timer that monitors the duration of an execution in this node.

Name Type Multiplicity Description

name attribute optional the name of the node

event element [0..*] supported event types: {node-leave}

transition element [0..*]the leaving transitions. Each transition leaving a node *must* have a distinct name.

exception-handler

element [0..*]a list of exception handlers that applies to all exceptions thrown by delegation classes thrown in this process node.

Name Type Multiplicity Description

name attribute required the name of the end-state

event element [0..*] supported event types: {node-enter}

exception-handler

element [0..*]a list of exception handlers that applies to all exceptions thrown by delegation classes thrown in this process node.

Name Type Multiplicity Description

common node elements See common node elements

Page 58: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Table 13.7.

13.3.8. process-state

Table 13.8.

13.3.9. super-state

Table 13.9.

13.3.10. fork

Table 13.10.

13.3.11. join

Table 13.11.

13.3.12. decision

Table 13.12.

Name Type Multiplicity Description

signal attribute optional{unsynchronized|never|first|first-wait|last|last-wait}, default is last. signal specifies the effect of task completion on the process execution continuation.

create-tasks

attribute optional

{yes|no|true|false}, default is true. can be set to false when a runtime calculation has to determine which of the tasks have to be created. in that case, add an action on node-enter, create the tasks in the action and set create-tasks to false.

task element [0..*]the tasks that should be created when execution arrives in this task node.

common node elements

See common node elements

Name Type Multiplicity Description

sub-process element 1 the sub process that is associated with this node

variable element [0..*]specifies how data should be copied from the super process to the sub process at the start and from the sub process to the super process upon completion of the sub process.

common node elements

See common node elements

Name Type Multiplicity Description

{end-state|state|node|task-node|process-state|super-state|fork|join|decision}

element [0..*]the nodes of the superstate. superstates can be nested.

common node elements See common node elements

Name Type Multiplicity Description

common node elements See common node elements

Name Type Multiplicity Description

common node elements See common node elements

Name Type Multiplicity Description

Page 59: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

13.3.13. event

Table 13.13.

13.3.14. transition

Table 13.14.

13.3.15. action

Table 13.15.

handler element

either a 'handler' element or conditions on the transitions should be specified

the name of a org.jbpm.jpdl.Def.DecisionHandler implementation

transition element [0..*]

the leaving transitions. The leaving transitions of a decision can be extended with a condition. The decision will look for the first transition for which the condition evaluates to true. A transition without a condition is considered to evaluate to true (to model the 'otherwise' branch). See the condition element

common node elements

See common node elements

Name Type Multiplicity Description

type attribute requiredthe event type that is expressed relative to the element on which the event is placed

{action|script|create-timer|cancel-timer}

element [0..*]the list of actions that should be executed on this event

Name Type Multiplicity Description

name attribute optionalthe name of the transition. Note that each transition leaving a node *must* have a distinct name.

to attribute requiredthe hierarchical name of the destination node. For more information about hierarchical names, see Section 7.5.3, “Hierarchical names”

{action|script|create-timer|cancel-timer}

element [0..*]the actions to be executed upon taking this transition. Note that the actions of a transition do not need to be put in an event (because there is only one)

exception-handler element [0..*]a list of exception handlers that applies to all exceptions thrown by delegation classes thrown in this process node.

Name Type Multiplicity Description

name attribute optionalthe name of the action. When actions are given names, they can be looked up from the process definition. This can be useful for runtime actions and declaring actions only once.

class attibuteeither this or ref-name

the fully qualified class name of the class that implements the org.jbpm.graph.def.ActionHandler interface.

ref-name attibuteeither this or class

the name of the referenced action. The content of this action is not processed further if a referenced action is specified.

accept-propagated-events

attribute optional

{yes|no|true|false}. Default is yes|true. If set to false, the action will only be executed on events that were fired on this action's element. for more information, see Section 7.4.4, “Event propagation”

{field|bean|constructor|configuration-property}. Specifies how the

Page 60: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

13.3.16. script

Table 13.16.

13.3.17. expression

Table 13.17.

13.3.18. variable

Table 13.18.

13.3.19. handler

Table 13.19.

config-type attribute optionalaction-object should be constructed and how the content of this element should be used as configuration information for that action-object.

{content} optional

the content of the action can be used as configuration information for your custom action implementations. This allows the creation of reusable delegation classes. For more about delegation configuration, see Section 13.2.3, “Configuration of delegations”.

Name Type Multiplicity Description

name attribute optionalthe name of the script-action. When actions are given names, they can be looked up from the process definition. This can be useful for runtime actions and declaring actions only once.

accept-propagated-events

attributeoptional [0..*]

{yes|no|true|false}. Default is yes|true. If set to false, the action will only be executed on events that were fired on this action's element. for more information, see Section 7.4.4, “Event propagation”

expression element [0..1]the beanshell script. If you don't specify variable elements, you can write the expression as the content of the script element (omitting the expression element tag).

variable element [0..*]

in variable for the script. If no in variables are specified, all the variables of the current token will be loaded into the script evaluation. Use the in variables if you want to limit the number of variables loaded into the script evaluation.

Name Type Multiplicity Description

{content} a bean shell script.

Name Type Multiplicity Description

name attribute required the process variable name

access attribute optionaldefault is read,write. it is a comma separated list of access specifiers. the only access specifiers used so far are

mapped-name

attribute optional

this defaults to the variable name. it specifies a name to which the variable name is mapped. the meaning of the mapped-name is dependent on the context in which this element is used. for a script, this will be the script-variable-name. for a task controller, this will be the label of the task form parameter and for a process-state, this will be the variable name used in the sub-process.

Name Type Multiplicity Description

class attibuteeither this or ref-name

the fully qualified class name of the class that implements the org.jbpm.graph.node.DecisionHandler interface.

Page 61: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

13.3.20. timer

Table 13.20.

13.3.21. create-timer

Table 13.21.

13.3.22. cancel-timer

Table 13.22.

13.3.23. task

config-type

attribute optional{field|bean|constructor|configuration-property}. Specifies how the action-object should be constructed and how the content of this element should be used as configuration information for that action-object.

{content} optional

the content of the handler can be used as configuration information for your custom handler implementations. This allows the creation of reusable delegation classes. For more about delegation configuration, see Section 13.2.3, “Configuration of delegations”.

Name Type Multiplicity Description

name attribute optionalthe name of the timer. If no name is specified, the name of the enclosing node is taken. Note that every timer should have a unique name.

duedate attribute requiredthe duration (optionally expressed in business hours) that specifies the the time period between the creation of the timer and the execution of the timer. See Section 11.1, “Duration” for the syntax.

repeat attribute optional

{duration | 'yes' | 'true'}after a timer has been executed on the duedate, 'repeat' optionally specifies duration between repeating timer executions until the node is left. If yes of true is specified, the same duration as for the due date is taken for the repeat. See Section 11.1, “Duration” for the syntax.

transition attribute optionala transition-name to be taken when the timer executes, after firing the the timer event and executing the action (if any).

cancel-event

attribute optional

this attribute is only to be used in timers of tasks. it specifies the event on which the timer should be cancelled. by default, this is the task-end event, but it can be set to e.g. task-assign or task-start. The cancel-event types can be combined by specifying them in a comma separated list in the attribute.

Name Type Multiplicity Description

name attribute optionalthe name of the timer. The name can be used for cancelling the timer with a cancel-timer action.

duedate attribute requiredthe duration (optionally expressed in business hours) that specifies the the time period between the creation of the timer and the execution of the timer. See Section 11.1, “Duration” for the syntax.

repeat attribute optional

{duration | 'yes' | 'true'}after a timer has been executed on the duedate, 'repeat' optionally specifies duration between repeating timer executions until the node is left. If yes of true is specified, the same duration as for the due date is taken for the repeat. See Section 11.1, “Duration” for the syntax.

transition attribute optionala transition-name to be taken when the timer executes, after firing the the timer event and executing the action (if any).

Name Type Multiplicity Description

name attribute optional the name of the timer to be cancelled.

Page 62: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Table 13.23.

13.3.24. swimlane

Table 13.24.

13.3.25. assignment

Table 13.25.

Name Type Multiplicity Description

name attribute optionalthe name of the task. Named tasks can be referenced and looked up via the TaskMgmtDefinition

blocking attribute optional

{yes|no|true|false}, default is false. If blocking is set to true, the node cannot be left when the task is not finished. If set to false (default) a signal on the token is allowed to continue execution and leave the node. The default is set to false, because blocking is normally forced by the user interface.

duedate attribute optionalis a duration expressed in absolute or business hours as explained in Chapter 11, Business calendar

swimlane attribute optionalreference to a swimlane. If a swimlane is specified on a task, the assignment is ignored.

priority attribute optionalone of {highest, high, normal, low, lowest}. alternatively, any integer number can be specified for the priority. FYI: (highest=1, lowest=5)

assignment element optionaldescribes a delegation that will assign the task to an actor when the task is created.

event element [0..*]supported event types: {task-create|task-start|task-assign|task-end}. Especially for the task-assign we have added a non-persisted property 绨蚧虺iousActorId to the TaskInstance

exception-handler

element [0..*]a list of exception handlers that applies to all exceptions thrown by delegation classes thrown in this process node.

timer element [0..*]

specifies a timer that monitors the duration of an execution in this task. special for task timers, the cancel-event can be specified. by default the cancel-event is task-end, but it can be customized to e.g. task-assign or task-start.

controller element [0..1]specifies how the process variables are transformed into task form parameters. the task form paramaters are used by the user interface to render a task form to the user.

Name Type Multiplicity Description

name attribute requiredthe name of the swimlane. Swimlanes can be referenced and looked up via the TaskMgmtDefinition

assignment element [1..1]specifies a the assignment of this swimlane. the assignment will be performed when the first task instance is created in this swimlane.

Name Type Multiplicity Description

class attribute required the fully qualified classname of an implementation of org.jbpm.taskmgmt.def.AssignmentHandler

config-type

attribute optional

{field|bean|constructor|configuration-property}. Specifies how the assignment-handler-object should be constructed and how the content of this element should be used as configuration information for that assignment-handler-object.

{content} optional

the content of the assignment-element can be used as configuration information for your AssignmentHandler implementations. This allows the creation of reusable delegation classes. for more about delegation configuration, see Section 13.2.3, “Configuration of delegations”.

Page 63: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

13.3.26. controller

Table 13.26.

13.3.27. sub-process

Table 13.27.

13.3.28. 条件

Table 13.28.

13.3.29. exception-handler

Table 13.29.

Name Type Multiplicity Description

class attribute optional the fully qualified classname of an implementation of org.jbpm.taskmgmt.def.TaskControllerHandler

config-type

attribute optional

{field|bean|constructor|configuration-property}. Specifies how the assignment-handler-object should be constructed and how the content of this element should be used as configuration information for that assignment-handler-object.

{content} either the content of the controller is the configuration of the specified task controller handler (if the class attribute is specified. if no task controller handler is specified, the content must be a list of variable elements.

variable element [0..*]in case no task controller handler is specified by the class attribute, the content of the controller element must be a list of variables.

Name Type Multiplicity Description

name attribute requiredthe name of the sub process. To know how you can test subprocesses, see Section 15.3, “Testing sub processes”

version attribute optionalthe version of the sub process. If no version is specified, the latest version of the given process will be taken.

Name Type Multiplicity Description

{content} required条件元素内容是beanshell表达式,评估结果为boolean.一个决策接受第一个转换 (as ordered in the processdefinition.xml) 来确定那一个表达式分解为 true.

Name Type Multiplicity Description

exception-class

attribute optional指明处理Java扔出的处理异常匹配的handler全称的类名.如果没有指明它处理所

有异常 exceptions (java.lang.Throwable).

action element [1..*] 动作清单用来当异常被这个异常handler处理的时候.

前一页 Up 后一页

第12章 记录 Home 第14章 安全

Page 64: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第14章 安全

jBPM安全特性依然在alpha阶段. 这章说明可插入的验证和授权. 部分框架可用,部分依然不能.

14.1. Todos

在framwork部分, 我们依然需要在当流程别执行时定义一部分许可用来验证jbpm引擎. 当前你能检查你自己的许可,当依然没有

默认的jbpm许可组.

只有一个默认的验证实现完成了.其他验证实现只是在想象中,还没有实现 . 验证是可选的,依然没有授权实现. 即使授权,也有数

个授权实现只是想象中,没有实现.

验证和授权两个部分,可以在framework里加如你自己的授权和验证机制.

14.2. 验证

验证是流程为谁的利益运行.jBPM 这个信息将从jBPM环境中可使用.造成 jBPM 总是在特殊的环境中运行比如webapp和EJB,swing应用程序或一些其他环境, 它总是让周围环境来执行验证.

在一些情况下, jBPM需要知道谁在运行代码.比如增加验证信息到流程日志记录谁做了什么. 另外一个例子是计算参与者.

jBPM 知道谁运行代码,是通过中央方法 调用org.jbpm.security.Authentication.getAuthenticatedActorId() . 方法将委托

org.jbpm.security.authenticator.Authenticator实现 . 指明一个实现的证明者, 你能配置jBPM 怎么检索当前验证的参与者.

默认证明者 org.jbpm.security.authenticator.JbpmDefaultAutenticator . 实现维护一个 ThreadLocal 验证的actorId堆栈. 验证

块用方法被标记 JbpmDefaultAutenticator.pushAuthenticatedActorId(String) 和

JbpmDefaultAutenticator.popAuthenticatedActorId() . 确定总是把这些放入 try-finally块. 实现push和pop方法,这是基本验证

class方便的方法.JbpmDefaultAutenticator 维护actorIds堆栈代替一个actorId理由是: 允许jBPM代码区分在流程代码运行

的用户和在jbpm引擎运行.

参看java doc文档.

14.3. 授权

授权是确认在验证允许用户安全操作之后.

jBPM 引擎和用户模式能校验如果用户被允许执行给定操作用API方法 org.jbpm.security.Authorization.checkPermission(Permission).

授权类将委托调用配置实现. pluggin接口对不同的授权策略API org.jbpm.security.authorizer.Authorizer.

如果包org.jbpm.security.authorizer 有一些实现授权的例子.大多数都是没有完全实现和测试过的.

另外一个依然需要做的是定义一组有jBPM引擎校验的jBPM许可和校验.一个例子,校验以确定用户有足够特权来结束任务通过API调用 Authorization.checkPermission(new TaskPermission("end", Long.toString(id))) ,在 TaskInstance.end() 方法

第14章 安全

前一页 后一页

前一页 Up 后一页

第13章jBPM 流程定义语言 (JPDL) Home 第15章TDD适合工作流

Page 65: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第15章. TDD适合工作流

15.1. 介绍工作流TDD

由于开发面向流程软件同开发其他软件没有什么不同, 我们相信流程定义也是容易可测试的.本章将展示你能用传统的JUnit不需要

任何扩展来测试你写的流程定义 .

开发周期应该尽可能的短. 软件源代码的修改应该立即被验证. 更好的, 没有任何中间的构造步骤. 下面的例子显示你怎样开发和

测试jBPM 流程没有任何中间步骤.

最常见的流程定义单元测试是执行场景.每个场景在一个单元测试方法中被执行并且将传回外部的触发器(read: 信号)到流程执行

并且验证在每个信号流程处于期望的状态.

我们来看一个这样测试的例子. 我们简化一个拍卖流程如下图形表示:

Figure 15.1. 拍卖测试流程

现在, 我们来写主要场景主要场景测试:

public class AuctionTest extends TestCase { // parse the process definition static ProcessDefinition auctionProcess = ProcessDefinition.parseParResource("org/jbpm/tdd/auction.par"); // get the nodes for easy asserting static StartState start = auctionProcess.getStartState(); static State auction = (State) auctionProcess.getNode("auction"); static EndState end = (EndState) auctionProcess.getNode("end"); // the process instance ProcessInstance processInstance; // the main path of execution Token token; public void setUp() { // create a new process instance for the given process definition processInstance = new ProcessInstance(auctionProcess); // the main path of execution is the root token token = processInstance.getRootToken(); } public void testMainScenario() { // after process instance creation, the main path of // execution is positioned in the start state. assertSame(start, token.getNode());

第15章. TDD适合工作流

前一页 后一页

Page 66: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

token.signal(); // after the signal, the main path of execution has // moved to the auction state assertSame(auction, token.getNode()); token.signal(); // after the signal, the main path of execution has // moved to the end state and the process has ended assertSame(end, token.getNode()); assertTrue(processInstance.hasEnded()); } }

15.2. XML 源

在你开始写执行情景, 你需要 ProcessDefinition . 最容易方式是通过 ProcessDefinition 对象来解析xml. 如果你代码完成敲入

ProcessDefinition.parse并且 激活代码完成. 那么你可以得到数种解析方法. 有基本的3中方式写 xml能被解析到

ProcessDefinition 对象:

15.2.1. 解析流程文档

流程文档是一个zip文件包含流程 xml 叫做 processdefinition.xml . jBPM 流程设计者读和写流程文档.比如:

... static ProcessDefinition auctionProcess = ProcessDefinition.parseParResource("org/jbpm/tdd/auction.par"); ...

15.2.2. 解析xml文件

其他情况, 你可能想手写 processdefinition.xml 文件然后打包进zip文件通过ant script.这钟情况下你可以选择 JpdlXmlReader

... static ProcessDefinition auctionProcess = ProcessDefinition.parseXmlResource("org/jbpm/tdd/auction.xml"); ...

15.2.3. 解析 xml字符串

最简单的选择是解析xml在单元测试里通过在线传统字符串.

... static ProcessDefinition auctionProcess = ProcessDefinition.parseXmlString( "<process-definition>" + " <start-state name='start'>" + " <transition to='auction'/>" + " </start-state>" + " <state name='auction'>" + " <transition to='end'/>" + " </state>" + " <end-state name='end'/>" + "</process-definition>"); ...

15.3. 测试子流程

Page 67: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

TODO (查看test/java/org/jbpm/graph/exe/ProcessStateTest.java)

前一页 Up 后一页

第14章.安全 Home 第16章可插入的架构

Page 68: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

第16章 可插入架构

jBPM 功能被分隔成模块. 每个模块有一个定义和执行(runtime)部分. 中央模块是图模块, 由ProcessDefinition 和

ProcessInstance组成 . 流程定义包含一个图并且流程实例表示一个图的执行.所有jBPM其他的功能被分组成了几个可选模块 .可选模块扩展图模块额外特性比如上下文(流程变量),任务管理,定时器, ...

Figure 16.1. 可插入架构

在jBPM里可插入架构也是唯一机制为jBPM引擎添加定制能力.定制流程定义信息通过 ModuleDefinition . 当 ProcessInstance被建立,它将为每一个在 ProcessDefinition的 ModuleDefinition产生实例. ModuleDefinition 用做 ModuleInstances工厂.

最完整的扩展流程定义信息方式是通过给流程档案加入信息通过实现 ProcessArchiveParser . ProcessArchiveParser能解析加入到流程档案中的信息 , 建立你的定制 ModuleDefinition并且把它加入到 ProcessDefinition.

public interface ProcessArchiveParser { void writeToArchive(ProcessDefinition processDefinition, ProcessArchive archive); ProcessDefinition readFromArchive(ProcessArchive archive, ProcessDefinition processDefinition); }

为了让它工作,定制 ModuleInstance必须在执行期间通知相关事件 .定制 ModuleDefinition 可增加 ActionHandler 实现在流程

事件之上用做callback handlers .

另外的方法,定制模块可以用AOP来绑定定制实例到流程执行. JBoss AOP 非常适合做这个工作因为它的成熟,易学并且也是

JBoss堆栈的一部分.

第16章 可插入架构

前一页

前一页 Up

第15章. TDD for workflow Home

Page 69: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Chapter 7. Graph

7.1. Overview

A process definition represents a formal specification of a business process and is based on a directed graph. The graph is composed of nodes and transitions. Every node in the graph is of a specific type. The type of the node defines the runtime behaviour. A process definition has exactly one start state.

A token is one path of execution. A token is the runtime concept that maintains a pointer to a node in the graph.

A process instance is one execution of a process definition. When a process instance is created, a token is created for the main path of execution. This token is called the root token of the process instance and it is positioned in the start state of the process definition.

A signal instructs a token to continue graph execution. When receiving an unnamed signal, the token will leave its current node over the default leaving transition. When a transition-name is specified in the signal, the token will leave its node over the specified transition. A signal given to the process instance is delegated to the root token.

After the token has entered a node, the node is executed. Nodes themselves are responsible for the continuation of the graph execution. Continuation of graph execution is done by making the token leave the node. Each node type can implement a different behaviour for the continuation of the graph execution. A node that does not propagate execution will behave as a state.

Actions are pieces of java code that are executed upon events in the process execution. The graph is an important instrument in the communication about software requirements. But the graph is just one view (projection) of the software being produced. It hides many technical details. Actions are a mechanism to add technical details outside of the graphical representation. Once the graph is put in place, it can be decorated with actions. The main event types are entering a node, leaving a node and taking a transition.

7.2. Process graph

The basis of a process definition is a graph that is made up of nodes and transitions. That information is expressed in an xml file called processdefinition.xml. Each node has a type like e.g. state, decision, fork, join,... Each node has a set of leaving transitions. A name can be given to the transitions that leave a node in order to make them distinct. For example: The following diagram shows a process graph of the jBAY auction process.

Chapter 7. Graph

前一页 后一页

Page 70: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Figure 7.1. The auction process graph

Below is the process graph of the jBAY auction process represented as xml:

<process-definition> <start-state> <transition to="auction" /> </start-state> <state name="auction"> <transition name="auction ends" to="salefork" /> <transition name="cancel" to="end" /> </state> <fork name="salefork"> <transition name="shipping" to="send item" /> <transition name="billing" to="receive money" /> </fork> <state name="send item"> <transition to="receive item" /> </state> <state name="receive item"> <transition to="salejoin" /> </state> <state name="receive money"> <transition to="send money" /> </state> <state name="send money"> <transition to="salejoin" /> </state> <join name="salejoin"> <transition to="end" /> </join> <end-state name="end" />

Page 71: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

</process-definition>

7.3. Actions

Actions are pieces of java code that are executed upon events in the process execution. The graph is an important instrument in the communication about software requirements. But the graph is just one view (projection) of the software being produced. It hides many technical details. Actions are a mechanism to add technical details outside of the graphical representation. Once the graph is put in place, it can be decorated with actions. This means that java code can be associated with the graph without changing the structure of the graph. The main event types are entering a node, leaving a node and taking a transition.

Let's look at an example. Suppose we want to do a database update on a given transition. The database update is technically vital but it is not important to the business analyst.

Figure 7.2. A database update action

public class RemoveEmployeeUpdate implements ActionHandler { public void execute(ExecutionContext ctx) throws Exception { // get the fired employee from the process variables. String firedEmployee = (String) ctx.getContextInstance().getVariable("fired employee"); // by taking the same database connection as used for the jbpm updates, we // reuse the jbpm transaction for our database update. Connection connection = ctx.getProcessInstance().getJbpmSession().getSession().getConnection(); Statement statement = connection.createStatement("DELETE FROM EMPLOYEE WHERE ..."); statement.execute(); statement.close(); } }

<process-definition name="yearly evaluation"> ... <state name="fire employee"> <transition to="collect badge"> <action class="com.nomercy.hr.RemoveEmployeeUpdate" /> </transition> </state> <state name="collect badge"> ... </process-definition>

7.3.1. Action configuration

For more information about adding configurations to your custom actions and how to specify the configuration in the processdefinition.xml, see Section 13.2.3, “Configuration of delegations”

7.3.2. Action references

Page 72: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

Actions can be given a name. Named actions can be referenced from other locations where actions can be specified. Named actions can also be put as child elements in the process definition.

This feature is interesting if you want to limit duplication of action configurations (e.g. when the action has complicated configurations). Another use case is execution or scheduling of runtime actions.

7.3.3. Events

Events specify moments in the execution of the process. The jBPM engine will fire events during graph execution. This occurs when jbpm calculats the next state (read: processing a signal). An event is always relative to an element in the process definition like e.g. the process definition, a node or a transition. Most process elements can fire different types of events. A node for example can fire a node-enter event and a node-leave event. Events are the hooks for actions. Each event has a list of actions. When the jBPM engine fires an event, the list of actions is executed.

7.3.4. Event propagation

Superstates create a parent-child relation in the elements of a process definition. Nodes and transitions contained in a superstate have that superstate as a parent. Top level elements have the process definition as a parent. The process definition does not have a parent. When an event is fired, the event will be propagated up the parent hierarchy. This allows e.g. to capture all transition events in a process and associate actions with these events in a centralized location.

7.3.5. Script

A script is an action that executes a beanshell script. For more information about beanshell, see the beanshell website. By default, all process variables are available in the script. After the script is executed, variable values of the script interpreter can be stored (or created) in the process variables. For example:

<process-definition> <event type="process-end"> <script> <expression> a = b + c; </expression> <out variable='a' /> </script> </event> ... </process-definition>

The 绨蚧虺ious script will load all process variables in the interpreter. Then the expression is evaluated, which requires that process variables b and c were present in the process variables when the script was executed. The out element specifies that the value of the scripting variable a has to be collected from the interpreter after the evaluation has completed and stored in the process variables (as variable a). When loading all the process variables into the interpreter or when there are variables that are not valid scripting variable names, you can specify the in variables analogue to the out variables.

7.3.6. Custom events

Note that it's possible to fire your own custom events at will during the execution of a process. Events are uniquely defined by the combination of a graph element (nodes, transitions, process definitions and superstates are graph elements). In actions, in your own custom node implementations, or even outside the execution of a process instance, you can call the GraphElement.fireEvent(String eventType, ExecutionContext executionContext);. The names of the event types can be chosen freely.

7.4. Superstates

A Superstate is a group of nodes. Superstates can be nested recursively. Superstates can be used to bring some hierarchy in the process definition. For example, one application could be to group all the nodes of a process in phases. Actions can be associated with superstate events. A consequence is that a token can be in multiple nested nodes at a given time. This can be convenient to check wether a process execution is e.g. in the start-up phase. In the jBPM model, you are free to group any set of nodes in a superstate.

Page 73: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

7.4.1. Superstate transitions

All transitions leaving a superstate can be taken by tokens in nodes contained within the super state. Transitions can also arrive in superstates. In that case, the token will be redirected to the first node in the superstate. Nodes from outside the superstate can have transitions directly to nodes inside the superstate. Also, the other way round, nodes within superstates can have transitions to nodes outside the superstate or to the superstate itself. Superstates also can have self references.

7.4.2. Superstate events

There are 2 events unique to superstates: superstate-enter and superstate-leave. These events will be fired no matter over which transitions the node is entered or left respectively. As long as a token takes transitions within the superstate, these events are not fired.

Note that we have created separate event types for states and superstates. This is to make it easy to distinct between superstate events and node events that are propagated from within the superstate.

7.4.3. Hierarchical names

Node names have to be unique in their scope. The scope of the node is its node-collection. Both the process definintion and the superstate are node collections. To refer to nodes in superstates, you have to specify the relative, slash (/) separated name. The slash separates the node names. Use '..' to refer to an upper level. The next example shows how to reference a neighbouring superstate:

<process-definition> ... <state name="preparation"> <transition to="phase one/invite murphy"/> </state> <super-state name="phase one"> </super-state> ... </process-definition>

The next example will show how to go up the superstate hierarchy

<process-definition> ... <super-state name="phase one"> <state name="preparation"> <transition to="../phase two/invite murphy"/> </node> </super-state> <super-state name="phase two"> </super-state> ... </process-definition>

7.5. Exception handling

The exception handling mechanism of jBPM only applies to java exceptions. Graph execution on itself cannot result in problems. It is only the execution of delegation classes that can lead to exceptions.

On process-definitions, nodes and transitions, a list of exception-handlers can be specified. Each exception-handler has a list of actions. When an exception occurs in a delegation class, the process element parent hierarchy is serached for an appropriate exception-handler. When it is found, the actions of the exception-handler are executed.

Note that the exception handling mechanism of jBPM is not completely similar to the java exception handling. In java, a caught exception can have an influence on the control flow. In the case of jBPM, control flow cannot

Page 74: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

be changed by the jBPM exception handling mechanism. The exception is either caught or uncaught. Uncaught exceptions are thrown to the client (e.g. the client that called the token.signal()) or the exception is caught by a jBPM exception-handler. For caught exceptions, the graph execution continues as if no exception has occurred.

Note that in an action that handles an exception, it is possible to put the token in an arbitrary node in the graph with Token.setNode(Node node).

7.6. Process composition

Process composition is supported in jBPM by means of the process-state. The process state is a state that is associated with another process definition. When graph execution arrives in the process state, a new process instance of the sub-process is created and it is associated with the path of execution that arrived in the process state. The path of execution of the super process will wait till the sub process instance has ended. When the sub process instance ends, the path of execution of the super process will leave the process state and continue graph execution in the super process.

When a subprocess is started, start-variables allow feeding of data from the super process into the sub process. Two variable names can be specified for each start-variable : the super process variable name and the sub process variable name. When the sub process is created, the value of the super process variable is copied in the sub process variable. The reverse is done with end-variable's. End variables allow collection of the results of the sub process into the super process.

7.7. Custom node behaviour

In jBPM, it's quite easy to write your own custom nodes. For creating custom nodes, an implementation of the ActionHandler has to be written. The implementation can execute any business logic, but also has the responsibility to propagate the graph execution. Let's look at an example that will update an ERP-system. We'll read an amout from the ERP-system, add an amount that is stored in the process variables and store the result back in the ERP-system. Based on the size of the amount, we have to leave the node via the 'small amounts' or the 'large amounts' transition.

Figure 7.3. The update erp example process snippet

public class AmountUpdate implements ActionHandler { public void execute(ExecutionContext ctx) throws Exception { // business logic Float erpAmount = ...get amount from erp-system...; Float processAmount = (Float) ctx.getContextInstance().getVariable("amount"); float result = erpAmount.floatValue() + processAmount.floatValue(); ...update erp-system with the result...; // graph execution propagation if (result > 5000) { ctx.leaveNode(ctx, "big amounts"); } else { ctx.leaveNode(ctx, "small amounts"); } } }

It is also possible to create and join tokens in custom node implementations. For an example on how to do this, check out the Fork and Join node implementation in the jbpm source code :-).

7.8. Graph execution

Page 75: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

The graph execution model of jBPM is based on interpretation of the process definition and the chain of command pattern.

Interpretation of the process definition means that the process definition data is stored in the database. At runtime the process definition information is used during process execution. Note for the concerned : we use hibernate's second level cache to avoid loading of definition information at runtime. Since the process definitions don't change (see process versioning) hibernate can cache the process definitions in memory.

The chain of command pattern means that each node in the graph is responsible for propagating the process execution. If a node does not propagate execution, it behaves as a wait state.

The idea is to start execution on process instances and that the execution continues till it enters a wait state.

A token represents a path of execution. A token has a pointer to a node in the process graph. During waitstates, the tokens can be persisted in the database. Now we are going to look at the algorithm for calculating the execution of a token. Execution starts when a signal is sent to a token. The execution is then passed over the transitions and nodes via the chain of command pattern. These are the relevant methods in a class diagram.

Figure 7.4. The graph execution related methods

When a token is in a node, signals can be sent to the token. Sending a signal is an instruction to start execution. A signal must therefore specify a leaving transition of the token's current node. The first transition is the default. In a signal to a token, the token takes its current node and calls the Node.leave(ExecutionContext,Transition) method. Think of the ExecutionContext as a Token because the main object in an ExecutionContext is a Token. The Node.leave(ExecutionContext,Transition) method will fire the node-leave event and call the Transition.take(ExecutionContext). That method will fire the transition event and call the Node.enter(ExecutionContext) on the destination node of the transition. That method will fire the node-enter event and call the Node.execute(ExecutionContext). Each type of node has its own behaviour that is implementated in the execute method. Each node is responsible for propagating graph execution by calling the Node.leave(ExecutionContext,Transition) again. In summary:

Token.signal(Transition) --> Node.leave(ExecutionContext,Transition) --> Transition.take(ExecutionContext) --> Node.enter(ExecutionContext) --> Node.execute(ExecutionContext)

Note that the complete calculation of the next state, including the invocation of the actions is done in the thread of the client. A common misconception is that all calculations *must* be done in the thread of the client. As with any asynchronous invocation, you can use asynchronous messaging (JMS) for that. When the message is sent in the same transaction as the process instance update, all synchronization issues are taken care of. Some workflow systems use asynchronous messaging between all nodes in the graph. But in high throughput environments, this algorithm gives much more control and flexibility for tweaking performance of a business process.

前一页 Up 后一页

Chapter 6. Persistence Home Chapter 8. Context

Page 76: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

JBPM.org

William Wang 整理 

工作流现状 ( 原文)

http://www.jboss.com/products/jbpm/stateofworkflow

作者Tom Baeyens 翻译dinghong

前言

    如果数据库系统( database systems)像受人尊敬的智者讲述的条理清晰的故事,那么工作流(workflow)就像一群乳臭未干的小子在大谈各自的“哲理”。之所以这样讲,我是想指出,工作流系统 (workflow management systems)还处于技术发展曲线( technology hype curve )上的初级阶段。在这个领域我们将面临一个激动人心的阶段。为了描述这一点,可以和关系数据库系统(RDBMS)做一个对比。当在软件开发团队中谈论RDBMS时,大部分人会有一个清晰的概念,在你和他们交流的时候,人们会通过轻微的点头表示认可或理解你所说的。可当使用工作流术语讨论工作流时,他们会摇头表示不同意,因为每个人对工作流术语都有不同的理解。

Figure 1: Workflow vs. RDBMS positioned in the hype-curve

    导致形成这种状况的原因之一,是在工作流中使用了过多的概念。在这个领域中的大量规范和工具没有一个是相似的。当然,它们相互之间有重叠并且会相互参考引证。      在介绍工作流时有一个话题必须包括,那就是工作流和业务流程管理(BPM)的关系。术语“工作流”通常描述人与计算机系统的一系列相关交互。在开发人员中,工作流经常被提及。有时,工作流的意思是指一些不同的UI界面。业务流程管理的范围比较广,相比之下工作流多半局限于技术领域。业务流程管理还从管理人员的角度涉及了非技术问题,比如分析、组织的效率。

    在本文中,我首先解释什么是工作流管理系统,然后介绍业务流程管理的优点。接下来描述一下为什么工作流市场乍看起来如此混乱。本文给出的主要结论是:选择工作流系统是想用工作流系统的公司,将要面对的 困难的事情。为此,本文的核心部分描述了一个流程定义(process definition)的四个层次,为你选择工作流提供一个基础。本文还用中立的语言描述了工作流和BPM的通用概念。 后,给出了一些规范和工具的指导性描述。

什么是工作流管理系统(WFMS)

定义

    工作流系统是以规格化的流程描述作为输入的软件组件,它维护流程的运行状态,并在人和应用之间分派活动。

    为了后面的描述,我们先定义一些基本的术语:流程定义(process definition)和流程实例(process instance). 一个

Page 77: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

流程定义是一个业务流程或过程的规格化描述。一个流程实例是流程定义的一个运行实体。 都目前为止,概念还比较清晰是不是?但当再深入一步时,我们就要小心使用文字了。如何阐述流程中的步骤,现在还没有一个统一的方式。这是各种工作流规范和工具之间主要的分歧。

    工作流系统另一个重要的职责是维护每一个流程运行的上下文信息。 流程上下文变量(process context variable) ,或简称变量,是与流程实例相关的变量。如,休假申请的开始日期、数据库中一条记录的键值、文档管理系统中一篇文档的索引等。通常在流程定义中声明这些变量,然后在流程实例生成时,这些流程变量被实例化。所有成熟的工作流管理系统都支持定制的变量类型。

目标领域(Target usage)

    使用工作流管理系统的目的之一是作为企业应用系统集成(EAI)的平台。在当前大部分企业级IT架构中,各种各样的异构(heterogeneous)应用和数据库运行在企业内网中。在这些系统被应用到组织时,都有一个清晰的目标。例如,客户管理、文档管理、供应链、订单、支付、资源计划等等。让我们称这些系统为专门应用( dedicated applications)。每一个专门应用都包含它们所支持业务流程的领域知识。这些专门应用中的自动化流程,被拼装到企业中更大的非自动化流程中。每当一个这样的专门应用安装并投入使用,都会带来涉及其他多个应用的新功能需求。企业应用系统集成(EAI)就是通过使用多个专门应用满足软件新需求的方法。有时,这只需要在两个应用之间提供数据通讯的通道。专门应用将很多业务流程硬编码在软件中。可以这么说,在你购买专门应用时,你是购买了一组固定的自动化业务流程。而工作流管理系统是不必事先知道问题域的相关信息的。工作流系统将业务流程描述作为输入并管理流程实例的执行,这使得它比专门应用更灵活(当然你也要花精力编写业务流程的规格化描述)。这就是为什么说工作流系统和专门系统是相互补充的。工作流系统可以用来管理全局的业务流程。如果专门应用支持你所需要的业务流程,那么使用专门应用。在此讨论的工作流系统的第一种使用方式就是:结合所有的专门应用,使用工作流系统构建一个EAI平台。

    工作流系统能够发挥很大价值的第二个使用方式是:协助涉及多人相关任务工作流软件的开发。为了达到这个目的,大部分工作流系统都有一个方便的机制,来生成执行任务的表单。对于专注于ISO 或者 CMM认证的组织,采用这种方式使用工作流系统能够显著提高生产率。 不用将过程用文字的形式写在纸上,工作流系统使你通过流程定义建模实现过程的自动化(如使用基于Web的应用)。

    工作流系统的第三种使用方式是:将工作流引擎嵌入到其他应用中。在前面我们谈到,专门应用将指定问题域相关的业务流程固化在软件中。开发专门应用的公司也可以将工作流引擎嵌入到他们的软件中。在这里,工作流引擎只是作为一个软件组件,对于应用的 终用户是不可见的。将工作流引擎嵌入到应用中的主要原因是为了重用(不重复发明轮子)和应用软件的可维护性。

The case for workflow

    对于引入工作流的组织,能够在软件开发和业务两个层次受益。

方便开发

    工作流管理系统能够简化企业级软件开发甚至维护。

降低开发风险 - 通过使用状态和动作这样的术语,业务分析师和开发人员使用同一种语言交谈。这样开发人员就不必将用户需求转化成软件设计了。 实现的集中统一 -业务流程经常变化,使用工作流系统的 大好处是:业务流程的实现代码,不再是散落在各种各样的系统中 。 加快应用开发 - 你的软件不用再关注流程的参与者,开发起来更快,代码更容易维护。

业务流程管理 (BPM)

    在自动化业务流程之前,分析并将它们规格化是一件艰苦但会有很好回报的工作。e-workflow.org对于分析流程能够带了的益处有不错的阐述:

提高效率 - 许多流程在自动化过程中会去除一些不必要的步骤 较好的流程控制 - 通过标准的工作方法和跟踪审计,提高了业务流程的管理 改进客户服务 - 因为流程的一致性,提高了对客户响应的可预见性 灵活 - 跨越流程的软件控制,使流程可以按照业务的需要重新设计。 业务流程改进 - 对流程的关注,使它们趋向于流畅和简单

为什么应当禁止使用术语“活动(activity)”...     流程定义通常用一些活动表述。我认为这是导致工作流领域所有混乱的主要原因。我告诉你为什么:因为术语“活动”混淆了状态(state)和动作(action)之间的差异。在流程中,状态 (或者说等待状态)代表了一种对外部参与者(actor)的依赖。在流程运行时,这意味着流程引擎必须等待,直到外部参与者通知工作流管理系统指定的状态完成了。比如,等待可进一步运行的认可。动作 是在流程运行过程中,工作流系统为响应指定事件(event)运行的一段程序逻辑(programming logic)。当流程运行过程中指定的事件发生时,工作流系统启动并执行这些动作。比如,当状态分配给一个参与者时,发一封Email。你也能看出,状态和动作是如此不同,因此使用同样的术语去描述这些概念是一个坏习惯。我的建议是避免使用术语“活动”,使用“状态”或者“动作”代替它。

Page 78: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

    我认为他们还遗漏了一个使用工作流系统 重要的因数:提高对迭代开发的支持。如果软件中业务流程部分不容易更改,组织就会花很大的精力在开发前的业务流程分析中,希望一次成功。但可悲的是,在任何软件项目开发中,这都很少能实现。工作流系统使得新业务流程很容易部署,业务流程相关的软件可以一种迭代的方式开发,因此使用工作流系统使开发更有效、风险更低。

缺失的一环(Missing link)

     我确实认为工作流系统是企业应用开发中缺失的一环。将企业业务流程逻辑在企业级软件中实现的缺省方式是分散的。这意味着业务流程逻辑散布在各种系统中,如EJB、数据库触发器、消息代理等等。这样得到的软件难于维护,结果,企业只能将改变业务流程软件作为 后的选择。他们经常能够做的是,改变流程以适应软件。上述问题也适用于采用大型外部ERP软件包的企业。进一步,假设我们认识到这个问题,并打算将一个流程相关的代码都集中起来。对于一个流程来说这很不错,但当你要实现多个流程时,你会看到管理状态和流程变量的代码被到处复制。

后,我们会整理这些代码放到一个集中的库中。好,...这就是一个工作流管理系统了,不用费心自己来实现,你可以从本文后面的列表中选择一个。

A closer look

WFMS interfaces

    一个工作流管理系统以流程定义作为输入。在这里,可以将流程定义看作UML活动图、UML状态图或者有限状态机。在提交一张费用单据、申请休假、要求一个报价、...之后,工作流系统负责维护这些流程定义的执行状态和上下文。为此,需要通知工作流系统状态的变化。运行流程的状态变化可以记录下来,以备监控管理。

Figure 2: Interfaces of a WFMS

定义   工作流系统的定义接口使流程开发人员能够部署流程定义。注意,这里的“流程开发人员”可以是业务分析师和软件开发人员的组合。

圈套(Pitfall) 许多工作流管理系统的开发商想使你相信,通过使用他们的图形化流程开发工具,只要业务分析师就可以生成流程定义。这种幻想源于“编程很难”这样的事实。开发商的销售人员喜欢说“看,你不用写一行代码”。不用写代码是好事,可大部分开发商在这点上走的太远,忽略了在某些场合提供一种将代码集成到流程定义中的机制是很适合的。在将工作流系统作为EAI平台时,必须在流程中集成代码。开发流程定义需要业

Page 79: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

执行   执行接口使用户和系统可以操作流程实例。流程实例是流程定义的执行。流程定义的控制流通过状态机描述。执行接口的两个主要方法是启动一个流程实例和通知工作流系统一个状态结束了。 应用    应用接口代表了由工作流系统发起的工作流系统和外部系统之间的交互。当一个用户或系统操作一个流程实例的运行时,会生成一些事件(如一个迁移的执行)。流程定义中可以指定一段响应一个事件的可执行代码逻辑,这段代码和组织内外部的其他系统打交道。 监控   管理人员通过监控接口获得流程运行的确切数据。有时,运行日志也可用于审计。

    这些是WfMC参考模型(reference model of the WfMC )中定义的五个接口中的四个。

流程定义的四个层次

     在下面这部分,我尝试回答这样的问题“什么是流程定义包括的内容?”。这是从各种规范和工具所使用模型的原则和概念中总结得来的,反映了大部分模型中通用的基本思想。流程定义的内容可以分为四个不同的层次:状态(state)、上下文(context)、程序逻辑(programming logic)和用户界面(UI)。

状态层

    所有状态和控制流的表述,都属于业务流程的状态层。标准编程语言中的控制流来源于Von Neuman体系。控制流定义了必须被执行的指令的顺序,控制流由我们书写的命令、if语句、循环语句等确定。在业务流程中的控制流基本与此一致。但在业务流程中不是使用命令而是使用状态作为基本元素。

    在流程中,状态 (或者说等待状态)代表了一种对外部参与者(actor)的依赖。状态的意思就像“现在X系统或某某人必须作某些事,在此等待直到参与者通知这些任务已完成”。状态定义了一种对外部提供结果的依赖。状态典型的例子是批准步骤(step)。

    流程定义中的状态也指定了执行依赖于哪个参与者。在活动图中,泳道(swimlanes)的标注代表这些参与者的名字。工作流系统使用这些信息构建任务列表,这是一般工作流系统都有的功能。如前所述,参与者可以是人也可以是系统。对于需要人参与的状态,工作流系统必须在运行时计算出具体的个人。这样的计算使工作流系统必须依赖于组织结构信息。关于这方面的一篇非常有趣的文章是在 further reading section 提到的“工作流应用中的组织管理”( 'Organizational Management in Workflow Applications')。

    流程定义的控制流包含一组状态和它们之间的关系。状态之间的逻辑关系描述了哪些执行路径可以同时执行,那些不可以。同步执行路径用分叉(forks)和联合(joins)建模,异步执行路径用判断(decisions)和合并( merges)建模。注意在大多数模型中,在每个状态之前都有一个隐式合并。

    UML活动图经常被用来做业务流程建模。作为一种直观和通用的表达,活动图在图形表述上有一个主要问题,就是没有区分状态和动作,它们都用活动来表示。缺少这种区分(导致状态概念的缺失)是学术派对UML活动图的主要批评。UML活动图的第二个问题是在UML2.0版中引入的。当多个迁移(transitions)到达一个活动时,以前的版本规定这是一个缺省合并(merge),在2.0版中规定这是一个需要同步的缺省联合(join)。在我看来,UML活动图的图形部分仍旧可以用来对业务流程状态层次建模,只要使用时对两条构建语义作如下的变化:

1. 在用图形表述业务流程时,只建模状态层(状态和控制流),不要包括动作。这意味着图形中的矩形都是状态而不是活动2. 如果多个迁移到达一个状态,缺省定义为不需要同步的合并(merges)

    在流程运行过程中,工作流系统用一个令牌(token)作为指针跟踪流程的状态。这相当于Von Neuman体系中的程序计数器。当令牌到达一个状态时,它被分配给工作流系统等待的外部参与者。外部参与者可以是个人、组织或者计算机系统。我们定义流程运行的执行人或系统为“参与者”(actor)。只有在工作流系统将令牌分配给一个参与者时,才需要访问组织结构信息。工作流系统通过分配令牌构建任务列表。

上下文层

    流程上下文变量(process context variable) ,或简称变量,是与流程实例相关的变量。流程开发人员可以使用流程变量存储跨越流程实例整个生命周期的数据。一些工作流管理系统有固定数目的数据类型,另一些你可以定义自己的数据类型。

    注意变量也可以用来存放引用( references)。一个变量可以引用如数据库中的记录、网络上的文件。什么时候使用引用,取决于使用引用数据的其他应用。

    和流程变量相关的另一个令人感兴趣的方面是:工作流系统如何将数据转化为信息。工作流是用于组织内部跨越各种异构系统实现任务和数据协同的。对于业务流程中人工执行的任务,工作流系统负责从其他相关系统,如SAP、数据库、CRM系统、文档管理系统收集数据。在业务流程的每一个人工步骤,只有相关联的数据项被从异构系统中收集和计算。通过这种方式,从不同系统来的数据被转换并展现为信息。

程序逻辑层

    如前所述,动作是在流程运行过程中,工作流系统响应指定的事件(event)执行的一段程序逻辑(programming logic)。

务分析师和软件开发人员的合作。一个好的图形流程设计工具应该能够支持这种合作。

Page 80: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

程序逻辑可以是二进制或源代码形式的、用任何语言或脚本编写的软件。程序逻辑层是所有这些软件片断和关于在什么事件发生时调用它们的信息的组合。程序逻辑的例子包括发Email、通过消息代理发消息、从ERP系统中拿数据和更新数据库。

用户界面层

    一个参与者通过向流程变量中填充数据的事件,来触发结束一个状态。比如,在请假的例子中,老板提供“同意”或“不同意”数据到流程中。某些工作流系统允许指定哪些数据可以填充到流程中,以及它们如何在流程变量中存储。通过这些信息,可以生成从用户收集信息的UI表单。基于流程定义生成用户提交表单的Web应用例子,可以访问 the jBpm online demo 。

工作流全景

可执行流程与工作流管理系统的比较(Executional processes versus a WFMS)

    当前在BPM领域中,关于可执行业务流程的规范有趋向于统一集中的趋势。 XLANG, WSFL 和BPML合并为基于交互(消息交换)的BPEL。BPEL在面向服务体系结构(SOA)的大背景下定义。它的前提条件之一是涉及的服务必须用WSDL声明。BPEL规定了一套XML语法,这套语法可以看作一种编程语言,用来描述包括对WSDL定义的服务调用的控制流。

    在可执行业务流程和基于状态的工作流管理系统所使用的方法中,我注意到了三点主要的区别:

基于状态与面向消息:基于状态的工作流系统以状态(或者活动)概念为中心。工作流引擎维护状态并计算从一个状态到另一个状态的迁移。另一方面,像BPEL这样的可执行流程以对输入消息响应的定义为中心。一组这些响应外加其他信息(other bells and whistles)可以看作一个业务流程。这也解释了为什么BPEL可以看作是对基于状态的工作流系统的某些方面的补充。一个响应输入消息的BPEL onMessage事件处理器,可以在工作流状态之间的迁移中执行。 流程实例ID与消息相关处理:可执行业务流程的复杂性之一来自消息相关性的处理。流程描述的一部分必须说明BPEL引擎如何从输入消息中确定具体流程的标识。这必须基于输入消息的一个数据项。而工作流系统在每个流程实例生成同时生成了实例ID,客户端在后续调用引擎API时使用这个ID。 工作流引擎API与抽象服务端点(endpoint):工作流系统提供一组集中的API,客户端通过调用API完成与所有流程实例的交互。在可执行业务流程中,每个流程表现为一个服务。这意味着对于每个流程定义都有一个不同的访问点。

学术界

    学术界对工作流的研究可以回溯到上个世纪七十年代。在当前,研究领域趋向于认为petr 网是所有流程定义语言之母。关于petri网已有大量先进的分析技术,去年在 2003 conference on Business Process Management上我有幸会晤了Petri教授。对于大部分人能够访问和理解的有关Petyri网 好的研究之一是工作流模式(workflow patterns)。工作流模式比较了大量的工作流管理系统并以petri网的术语表述了通用流程建

模概念。

开放源代码项目

     后我们看看真实世界中的工作流管理系统。选择一个工作流管理系统是一件困难的事情,但有选择总比没有选择好。:-) 本文阐述工作流基本概念的目的之一,就是使你能够作更好的选择。但我也意识到,对于现在的软件架构师来说,选择工作流系统是一件 具挑战性的工作。

    下面的列表来源于三个地方:my previous article , the list of Carlos E Perez , 和 list by Topicus .

jBpm - jBpm是本文作者编写的一个灵活可扩展的工作流管理系统。作为jBpm运行时server输入的业务流程使用简单强大的语言表达并打包在流程档案中。 jBmp将工作流应用开发的便利性和杰出的企业应用集成(EAI)能力结合了起来。jBmp包括一个Web应用程序和一个日程安排程序。jBmp是一组 J2SE组件,可以作为J2EE应用集群部署。 OpenEbXML - OpenebXML项目致力于提供一个ebXML框架,主要支持不久将由 UN/CEFACT和OASIS发布的ebXML规范2.0版。 Werkflow - Werkflow是一个灵活可扩展的基于流程和状态的工作流引擎。它的目标是满足可以想象的所有工作流程,从企业级的业务流程到小范围的用户交互流程。通过使用可插拔和分层结构,可以方便地容纳各种工作流语义。 OSWorkflow - OSWorkflow 独到之处是绝对的灵活。 wfmOpen - WfMOpen是WfMC和OMG中所谓工作流设施(workflow facility) (工作流引擎)的J2EE实现。工作流通过扩展的XPDL描述。 OFBiz - OFBiz工作流引擎基于WfMC和OMG的规范,使用XPDL作为流程定义语言。 ObjectWeb Bonita - Bonita是一个符合WfMC规范、灵活的协同工作流系统。对于各种动作如流程概念建模、定义、实例化、流程控制和用户交互等提供了全面的集成图形工具。 100% 基于浏览器、使用SOAP和XML数据绑定技术的Web Services封装了已有的工作流业务方法并将它们以基于J2EE的Web Service形式发布。基于活动预测模型的第三代工作流引擎。 Bigbross Bossa -速度非常快、轻量级的引擎,使用富有表达能力的Petri网定义工作流,不要求关系数据库,使用简单,能和Java应用集成。事实上,它是按嵌入式设计的。 XFlow - XFlow运行于EJB和servlet容器中。 Taverna - Taverna项目的目标是提供一种语言和软件工具,方便在eScience中使用工作流和分布计算技术。 Enhydra Shark - Shark完全基于WfMC和OMG标准,使用 XPDL作为工作流定义语言。流程和活动的存储使用Enhydra DODS。 PowerFolder - PowerFolder包括开发人员使用的studio,管理环境和一个运行时引擎。 Breeze - Breeze一个轻量级、跨平台、基于组件的工作流引擎原型。 Open Business Engine - Open Business Engine是一个开放源码的Java工作流引擎,支持WfMC规范,包括接口1(XPDL)、接口2/3(WAPI)和接口5。OBE为活动的运行提供了一个可控的集中环境。OBE主要基于J2EE实现。 OpenWFE - OpenWFE是一个开放源码的Java工作流引擎。 它包括可升级的三个组件:引擎、工作列表和Web界面。它的流程定义语言虽然使用XML格式,其灵感来源于 Scheme,一种Lisp方言。 Freefluo - Freefluo是一个使用Web Service的工作流协同工具,可以处理WSDL的Web Service调用。支持两种XML格式的工作流语言:IBM的WSFL和XScufl。Freefluo非常灵活,它的核心是不与任何工作流语言或执行架构关联的可重用协同框

Page 81: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

架。 Freefluo包括可执行使用WSFL一个子集描述的工作流的运行库。 ZBuilder - ZBuilder3是第二代工作流开发管理系统,也是一个开放源码产品。它为不同的工作流引擎和工作流定义了一组标准的JMX管理接口。 Twister - Twister的目标是提供新一代、易集成、应用Java领域中 新成果、面向B2B的工作流解决方案。流程引擎基于BPEL业务流程规范和Web Service标准。 Con:cern - con:cern工作流引擎基于扩展的案例(case)处理方法,流程由一组具有前后条件的活动组成。

商业软件提供商

Bea's WLI Carnot Dralasoft Filenet Fujitsu's i-Flow IBM's holosofx tool Intalio Joinwork (译者加:-) ) Lombardi Oakgrove's reactor Oracle's integration platform Q-Link SAP's NetWeaver Savvion Seebeyond Sonic's orchestration server Staffware Ultimus Versata WebMethod's process modeling

工具目录

http://dmoz.org/Computers/Software/Workflow/Products/ A collection of links to tools for modelling business processes and workflows maintained by Bart-Jan Hommes at TU Delft, the Netherlands.

规范

    Michael zur Muehlen作了一个所有工作流相关规范的介绍性的 幻灯片,很不错。

    我同意John Pyke 和 Wil van der Aalst 的观点:工作流标准还处于制定阶段。现在存在大量相互丛叠的规范。

    在我看来,导致规范如此之多而同时每个规范的应用又很有限的原因是,在工作流 基础概念上大家达成的共识很少。工作流是 容易让你感到心烦的话题,因为工作流本身的概念会和其他相关概念和技术混淆在一起。可以举一个具体的例子,比如说工作流完全是对Web Service的补充。你可以通过暴露接口以Web Service的方式访问一个工作流管理系统,但是不能假定总是必须通过Web Service接口访问工作流系统接口。一些规范造成了这样的假设。除了Web Service,其他容易混淆的概念和技术包括:Email、流程之间的通讯、Web应用和组织结构。

    在工作流领域第一个致力于标准化工作的是Workflow Management Coalition (WfMC),开始于 1993。 WfMC发布的 参考模型很不错,它定义了工作流管理系统和其他相关部分之间的接口。WfMC的另一项成果是XPDL规范。 XPDL定义了描述工作流声明部分(declarative part)的XML结构。我个人认为,参考模型和XPDL是目前 好的规范。

JSR 207: Java的流程定义 -是由 Java Community Process (JCP) 发起,如何在J2EE应用服务器中实现业务流程自动化的标准。其基本模型是定义一个特殊类型的ejb session bean,作为一个业务流程的接口。JSR207标准化一组XML元标记(meta tags)作为JSR175元数据的一部分。JSR207 将session bean和元数据作为ejb容器的输入,然后生成绑定方法的代码,这些方法在元数据中描述。此规范还处于初级阶段,没有发布任何内容。专家小组成立于 March 2003. WfMC's XPDL - WfMC是由约300家成员参加的组织,基于参考模型定义了一系列的标准。参考模型用用例(use case)的形式描述了工作流系统和其他相关部分之间的关系。XPDL是WfMC制定的描述业务流程控制流(control flow )的XML格式规范。 ebXML's BPSS - ebXML是协同流程的相关标准集,主要关注不同公司流程之间的通讯。可以看作EDI的继承者。 ebXML是由OASIS和UN/CEFACT联合发起。 BPSS 是ebXML的规范,其中的概念和本文阐述的很接近。 BPMI's BPML & WSCI - (Intalio, Sun, SAP, ...)BPMI 也定义了一个规范 (BPMN) ,描述如何将“可执行”业务流程可视化的表现。 BPEL - (Microsoft, BEA, IBM, SAP & Siebel) BPEL由一系列基于消息交换的规范( XLANG, WSFL, BPML)产生。还有一个将此规范引入到Java的提案: BPELJ。此规范描述如何处理输入的消息,而不是对流程状态进行建模。就像本文提到的,它不是一个关于业务流程规格化定义的规范。简单的说,可以将它看作XML形式的编程语言,提供将WSDL-Services组合成控制流的能力。顾名思义,此规范重点在(也不只限于)Web Service。 OMG's Workflow management facility - 基于WfMC规范,定义如何向CORBA转换。 UML - UML定义了建模和设计软件系统的9类图。每类图包括可视化的表示和语义。其中活动图的目的就是要可视化的表现业务流程。 注意到在一个流程定义包含四个层次的内容,我想指出的是:一个流程定义包含的内容远远多于它的可视化部分。UML只涉及了可视化部分。 RosettaNet - RosettaNet主要定义了一组 Partner Interface Processes (PIP). 一个 PIP 描述了一个有两个交易参与者、包括消息格式的流程。

Page 82: JBoss jBPM 3 - read.pudn.comread.pudn.com/downloads66/ebook/239203/jBPM_3.0.pdfJBoss jBPM 3.0 Workflow and BPM 实践 目录 1. 介绍 1.1. 综述 1.2. The JBoss jBPM 新手工具箱

UBL - The Universal Business Language (UBL)定义了用于不同组织间通讯的XML文档标准库。可以看作是对ebXML的补充,因为ebXML只定义了建立组织间流程的基础。此规范的竞争对手是 RosettaNet标准中的一个子集。

结论

    我在本文中指出工作流市场还属于年轻而又混乱(young and wild)的阶段,但已经有可靠的工具存在了:

1. 到目前,像J2EE和.NET这样成熟的集成平台才可用。在这样一个平台上运行工作流管理系统才能真正发挥工作流系统的附加价值。这也是为什么只有在今天,工作流系统才被重新发现。

2. 在 'The case for workflow'一节,我们介绍了引入工作流管理系统,是如何同时在技术和业务上带来投资回报的。 3. 工作流在技术发展曲线的位置表明,BPM和工作流中使用的概念还需要明确。 4. “开放源代码项目”和“商业软件提供商”列表中的工具,可以让你获得工作流和业务流程管理的益处。

    从以上所有这些中能得到的结论是:

1. 规范还没有成熟,没有标准被大范围采用 2. 对于现在想应用BPM的公司来讲,比较工作流系统是一个极其困难的挑战 3. 尽管标准化工作慢了一拍,可好的工作流管理系统还是有的。这对于已经在挑选工作流系统的组织来说是一个好消息。

    我希望本文能够激发你对工作流的兴趣并且能够为你进行有效的对比提供正确的背景知识。

Further reading

Workflow Patterns -Wil van der Aalst教授的工作流模式学术研究网站 ebpml.org - 有关业务流程管理和工作流的网站,信息量大、全面 Business process management group - The Business Process Management Group (founded in 1992) is a global business club exchanging ideas and best practice in business process and change management. Enix - 英国流程管理顾问公司,在网站上有不错的内容 ebizq.net - Commercial community that has booths, webinars and other interesting stuff put together in a nice website. An introduction to petri nets - The title says it all. Organizational Management in Workflow Applications - An interesting article that discusses the relation between business processes and the organisational data involved. Web services orchestration - an HP-paper that reviews the emerging technologies tools and standards. (Januari 2003) Business process standards for web services - An article that discusses the various aspects involved in workflow and BPM.

Thanks

    A special thanks for Gustavo Maciel Dias Vieira and Jef Vanbockryck for their valuable feedback on the draft versions of this article.

about the author Tom Baeyens leads the jBpm support organisation, specialized in Java, workflow and business process management. His expertises are both at a technical, analysis and at a business level. Tom is the founder of jbpm.org, an open source workflow engine. Tom is also a member of the expertgroup of the JSR 207: Process Definition for Java . Tom Baeyens can be contacted at tom at jbpm.org

译者 dinghong 轻量级嵌入式Java工作流系统Joinwork的设计开发者。email:[email protected]