﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-飞得更高-文章分类-jbpm</title><link>http://www.blogjava.net/abram/category/32109.html</link><description>有朋自远方来</description><language>zh-cn</language><lastBuildDate>Fri, 20 Jun 2008 01:10:58 GMT</lastBuildDate><pubDate>Fri, 20 Jun 2008 01:10:58 GMT</pubDate><ttl>60</ttl><item><title>JBPM阶段性工作总结（转载）</title><link>http://www.blogjava.net/abram/articles/208903.html</link><dc:creator>chong</dc:creator><author>chong</author><pubDate>Wed, 18 Jun 2008 08:01:00 GMT</pubDate><guid>http://www.blogjava.net/abram/articles/208903.html</guid><wfw:comment>http://www.blogjava.net/abram/comments/208903.html</wfw:comment><comments>http://www.blogjava.net/abram/articles/208903.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/abram/comments/commentRss/208903.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/abram/services/trackbacks/208903.html</trackback:ping><description><![CDATA[网站: <a href="http://www.javaeye.com/" target="_blank">JavaEye</a>&nbsp; 作者: <a href="http://zwchen.javaeye.com/" target="_blank">zwchen</a>&nbsp; 链接：<a style="color: red" href="http://zwchen.javaeye.com/blog/123322" target="_blank">http://zwchen.javaeye.com/blog/123322</a>&nbsp; 发表时间: 2007年09月12日 <br />
<br />
声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！ <br />
<br />
快要离职了，工作交接期。但发现技术调研这种东西交接效率非常低啊。下面是自己写的一篇文档，算是做个备忘了。 <br />
<br />
<strong>一、工作概述</strong> <br />
近一个月左右，对工作流，特别是开源工作流JBPM进行了一定的技术调研和尝试，现将工作总结一下。 <br />
<br />
我主要的工作时间花在以下几个方面，它们也是学习、研究工作流的一般途径： <br />
1、JBPM3.2.1官方UserGuide（21章）通读了几遍，包括官方的examples、forum、wiki、apidoc。这五份资料来源是我认为最重要的。 <br />
2、google（english）、Javaeye和csdn相关工作流技术文章和评论，特别是&#8220;银狐999&#8221;的工作流blog。 <br />
3、国内OA、工作流、BPM产品的演示和功能介绍，如joinwork，思维加速，西安协同，摩卡等。 <br />
4、xflow、osworkflow、Willow、agileFlow等国内外开源工作流了解。 <br />
5、几本重要的工作流、BPM相关书籍和workflow模式，最重要的两本书是《OReilly Essential Business Process Modeling》、《MIT Press - Workflow Management--Models, Methods &amp; Systems》。 另外JBPM的UserGuide第四章Graph Oriented Programming里有一个jbpm.gop.zip下载包，它就是JBPM引擎的mini版，几乎涵盖有JBPM引擎的绝大部分，如流转、分支、合并、、并行、同步、异步、事件、Action、表单。 <br />
6、JBPM的一个请假流程从页面到持久化的整个demo开发（约花两周时间），例子来源于csdn上一个非常典型的例子，有顺序、并发、互斥、条件分支等情形。另外，特别针对JBPM源码进行跟踪调试（四天）。 <br />
7、对当前项目的若干Use Case的深入分析，如流程图表示、流程实现。 <br />
<br />
<br />
<strong>二、JBPM环境和开发</strong> <br />
<strong>JBPM开发环境</strong>JBPM我是从3.1.4版本开始研究的，但发现3.1.4版的designer在推荐的eclipse3.12下画流程图时，eclipse总是处理僵死状态，一个操作都要5s以上。无奈之下，下载JBPM3.2版本，该版本在eclipse3.1.2下designer无法正常使用。但在eclipse3.3，也就是官方刚出来的Europa版本下，其designer可以正常使用，但代码开发时，也是僵死状态，而在eclipse3.12下开发正常。所以，我现在的做法是，用JBPM的3.2.1版本，用eclipse的3.12做开发和调试，用eclipse3.3做流程可视化设计。另外，3.2.1对mail这类节点有支持。 <br />
<br />
<strong>JBPM控制台</strong> <br />
JBPM的管理控制台从3.1.4到3.2.1有非常大的改进，如中文问题、界面、流程发布等。但在实际项目中，我们还是几乎无法使用，理由如下： <br />
1、该管理控制台还是很粗糙，只有最基本的功能，没有权限、组织结构、细粒度的流程管理等功能，另外必须汉化。 <br />
2、其流程designer默认是生成JSF表单，也就是说整个管理控制台和流程开发最方便是JSF做表示层，这不符合我们当前的项目实际。另外，用自己的业务表，而不是JBPM自带的活表（数据库对应jbpm_variableinstance表），也就意味着JSF表单没法用上。 <br />
3、我们的流程存在大量中国特色的定制，如回退、临时流转、跳越，不可能将流程用JBPM的designer设计好，发布到控制台就ok这么简单。 <br />
<br />
当前，我们的项目需要流程控制台，但应该是完全自己开发，可以借鉴JBPM后台的设计实现思想，特别是流程查看时的流程图显示；另外我们还需要table格式的详细流转过程。 <br />
一般来说，控制台做得很强大的工作流系统，都是standalone方式运行，而不是我们现在的embeded方式。 <br />
关于JBPM控制台入门知识，JBPM官方wiki有非常详细的介绍。 <br />
<br />
<strong>JBPM的开发模式</strong> <br />
实际的JBPM开发，我觉得应该注意以下几个问题： <br />
<strong>1、业务处理的位置</strong> 我们知道，在MIS系统，如OA项目中引入工作流，主要是将流程逻辑和业务逻辑分开，流程数据持久化到流程引擎表，业务数据持久化到业务表。这就涉及到业务逻辑在哪里处理的问题。在JBPM中，是在ActionHandler还是在Business Service中？ <br />
<strong>ActionHandler中：</strong>我们将业务在JBPM的回调接口ActionHandler实现中处理，将业务表单对象通过ContextInstance的setTransientVariables()传入，在ActionHandler中持久化，也就是说，ActionHandler是我们的业务处理主体，可以通过在Task实例中记录业务表单ID。另外，数据库的Connection可以通过ActionHandler的ExecuteContext参数取得。 <br />
<strong>Business Service中：</strong>这个Service就对应于用Spring框架时的Service，我们可以在service方法里面调用JBPM的API，如JbpmConfiguration.getInstance().createJbpmContext(); TaskInstance ti = jContext.getTaskInstance(tiid); 将业务数据都持久化到JBPM的活表里，这样只在一个数据库Conntection上，可以避免分布式事务的问题。 <br />
上面两种方式，第一种是我推荐的，其基本思想是将工作流引擎当成一个集成框架，一切以流程为主线。第二种是将工作流引擎当成辅助的第三方库。两种方式对系统的侵入性都非常大，无侵入性我认为不现实。 <br />
参考： <br />
<a href="http://www.processdriven.org/process_liberation.html" target="_blank">http://www.processdriven.org/process_liberation.html</a> <br />
<a href="http://weblogs.java.net/blog/edgars/archive/2007/08/understanding_j_1.html" target="_blank">http://weblogs.java.net/blog/edgars/archive/2007/08/understanding_j_1.html</a> <br />
<br />
<strong>2、业务数据的存储</strong> 把业务数据持久化到JBPM的活表jbpm_variableinstance中，可以很容易地进行字段级别的权限控制，灵活的表单自定义，而且可以在JBPM的管理控制台上二次开发，将开发的工作量降到最低，而这是大多数商业工作流产品实现的目标。但是，活表对于实时的业务报表统计分析很低效，有时不可能，因为表单项是离散的，并且不是最重要的关注点。关注点可能是流程的执行效率统计，也就是流程数据统计。 <br />
成熟的工作流管理系统（工作流引擎只是其中一个组成部分）往往是一个任务或节点对应一个表单，这样很便于表单自定义，将流程设计、表单定义、权限控制、组织结构和任务分配一气呵成。我理解的表单，只是如同Struts里面的ActionForm，只是页面数据的收集和呈现形式，具体到这些表单怎么持久化，采用JBPM的活表或自定义的业务表均可，但我倾向后者。 <br />
<br />
<strong>3、面向流程的MIS系统的开发过程</strong> 对于一般的MIS系统开发，很强调领域分析、系统设计，也就是大量的UML图。这样的系统，往往可以抽象为增删改查CRUD，可以按页面分配工作量，增删改查都是无状态的，也就是说开发&#8220;增&#8221;并不影响&#8220;改&#8221;，一个操作一个业务，各业务操作互不影响、耦合。但有清晰流程的系统就不同，每一个业务操作都是有状态的，譬如一个OA的发文流程，可能有十来个步骤，各级领导审核、审批、查阅，每一步的操作都影响后面的业务流向，而且必须有各业务相关人员协作才能完成该发文目标，这样通过CRUD方式去理解这个系统就无法理清业务，如果通过流程驱动方式去建模，那么事情就简单了。 <br />
这样，就引发了一个问题：流程驱动的MIS系统，怎么制定软件开发过程？如果大家看过工作流产品（关键字：工作流、OA、协同、BPM）的demo介绍，就会知道，工作流系统的开发，往往和流程设计、表单设计打交道，在我们的成果物中（RUP中是artifact、工件），没有OO的概念，领域分析让位于流程分析：难道我们真的需要一个请假单LeaveForm的Domain？做报表系统开发，应该也没有强调Domain吧？因为它是数据驱动，没有强调业务层。 <br />
所以，我认为，流程驱动的业务系统开发，不要将概要设计、详细设计往上面套，它们的重点往往没有放在流程设计和实现这个根本问题上。也许，概要设计、详细设计这种瀑布开发过程挺适合低端的外包项目，譬如对日的外包，将低端Coding外包给中国公司。前提是，别人的详细设计可以确定95％以上需求，需求不明确带来的风险很小。另外，在用JBPM开发过程中，也许业务主要写在JBPM这个框架的ActionHandler回调接口中，我们详细设计的顺序图中的call或sendMessage，不适合反映这种过程，因为ActionHandler的lifecycle我们无法控制。那么详细设计的意义何在？ <br />
那么，软件过程怎么定？我认为还是敏捷一点，只关注三点：用户需求（详细的用例文档和原型）、流程设计、流程实现。文档只集中在第一点。 <br />
我认为，参考基于成熟的商业工作流产品开发模式，就是我们系统的开发的模式。 <br />
<br />
<strong>三、JBPM对常见流程问题的解决</strong> <br />
JBPM的API文档非常匮乏，但是，JBPM的源码内部有很多注释，其代码可读性非常强，核心代码我认为不超过1w行，引擎核心代码也许只有两三千行。另外，阅读源码，最好对UML活动图、Petri网、Workflow模式较熟悉，譬如Join. setDiscriminator()，如果不了解Workflow模式的Discriminator模式，该方法就不知所措。 <br />
Process本质上，只有两个对象：Node和Transition（节点和有向弧），只要这两类对象就可以完整绘出一个流程图，当然，Node有很多子类，譬如Start、End、Fork、Join、Decision等。 <br />
JBPM的过程调度，是通过Token在流程节点之间转移实现的。譬如TaskInstance.end()的时候，调用Token.signal()，在signal()内部，依次调用：Node.leave()，Transition.take()，Node.enter()，这三个调用依次引发如下三个event：node-leave，transition，node-enter，在event内部，就处理我们自定义的ActionHandler和记日志。从中我们可以看出，事件（event）处理和Token调度是分离的。上面的三个event是重复循环的，可以驱动流程向前进行：离开当前节点过渡进入下一节点。 <br />
上面就是JBPM的大致调度过程，清晰、简洁。 <br />
参考： <br />
JBPM引擎架构：<a href="http://blog.csdn.net/james999/archive/2007/09/02/1769592.aspx" target="_blank">http://blog.csdn.net/james999/archive/2007/09/02/1769592.aspx</a> <br />
JBPM微型架构实现：<a href="http://docs.jboss.com/jbpm/gop/jbpm.gop.zip" target="_blank">http://docs.jboss.com/jbpm/gop/jbpm.gop.zip</a> <br />
<br />
下面我对JBPM对工作流中常见问题的解决方案总结一下，基本上都来源于网络，自己试验了一下，很可行。 <br />
<strong>1、互斥任务</strong> <br />
譬如，员工请假流程中，员工请假申请提交后，系统应该创建两个并发任务：员工取消和主管审批，只要任何一个任务结束，另外一个就应该结束。 <br />
一种实现方式是，在请假申请Node后Fork出两个Node，员工取消和主管审批，它们Transition 的ActionHandler里结束另外一个Node的TaskInstance。 <br />
另外一种实现方式是，在一个Node里创建上面两个Task，在Node节点里设置属性signal="first" end-tasks="true"。signal="first"指一个任务结束，当前节点就流转；end-tasks="true"指结束该节点时自动结束其它没有完成的任务。 <br />
参考：<a href="http://jbpm.group.javaeye.com/group/blog/59741" target="_blank">http://jbpm.group.javaeye.com/group/blog/59741</a> <br />
<br />
<strong>2、动态创建任务，会签或任务分派</strong> <br />
像会签这类动态创建任务的情形，用流程图很难描述，所以一般是通过代码手工创建，JBPM为这提供了很方便的接口。 <br />
JBPM的实现方式。在task-node设置create-tasks="false"，在该task-node的event-enter事件中，自定义ActionHandler，处理任务创建的工作。 <br />
说明：对JBPM的API用得得心应手，必须对其API设计实现、引擎思想有较深入理解，譬如Event机制、Token调度、Workflow模式等，其API绝对没有Servlet API那么简单，容易上手。 <br />
参考：<a href="http://www.cnblogs.com/amushen/archive/2007/07/03/804237.aspx" target="_blank">http://www.cnblogs.com/amushen/archive/2007/07/03/804237.aspx</a> <br />
<br />
<strong>3、循环节点，文件传阅</strong> <br />
在默认的JBPM的designer里无法画出指向自身的有向弧，可以先在该节点的XML流程定义文件里写出指向自身的Transition，这样在图形显示下就会出现指向自身的有向弧。当然，重复创建两个类似的节点，之间有往返有向弧也可以实现。 <br />
<br />
<strong>4、并发子流程</strong>JBPM自身对子流程的支持不够灵活，如只能创建一个子流程（ProcessState.setSubProcessDefinition()而不是addSubProcessDefinition()） <br />
一种解决方案是用流程的Hierarchy分级结构方式，请参考：<a href="http://jeffreyhsu.javaeye.com/blog/29917" target="_blank">http://jeffreyhsu.javaeye.com/blog/29917</a> <br />
<br />
............... <br />
............... <br />
<br />
<strong>5、客户的Visio流程原型实现的探讨</strong> <br />
该流程原型，要求把JBPM的流程定义模块重新实现，有一定难度。但我认为，实现是完全可以的，但初步实现需要一个多人月的时间（以自己目前的能力）。 <br />
作为我个人的角度，我觉得Leader应该给开发人员充分的授权，信任开发人员，时间自由支配，定一个大致milestone就可以了。前段时间的技术调研太浮躁，一天一个方向，根本就没有调研深度。做一件事情需要多少时间就是多少时间，人为主观去控制，注定会失败的。 <br />
如果现在想按客户的要求实现，技术比以前的预想难多了，因为现在的流程定义是活的，相当于我们做了一个流程管理控制台和流程设计器。可以做，但风险大，不过，静下心来，是完全可以完成的，因为JBPM这部分相关代码只有几千行（千万不要忘了，JBPM只是一个naked流程引擎，不是工作流管理系统）。项目现在面临的一个问题是，前期开发有一个时间瓶颈，核心代码没有开发出来，后面的开发无法进行，以当前的管理模式，势必会让前期开发人员浮躁（自由的思想才会有深度，有创造力）。 <br />
<br />
<strong>客户原型实现看法：</strong> <br />
流程定义和修改：JBPM有JpdlXmlReader，负责XML流程定义解析的，把该类和其关联类弄明白就差不多了，估计约两天时间，我花完整一天时间读过，不太难。 <br />
节点编辑，出口编辑：解析过程同上， <br />
数据项编辑：利用JBPM自己的活表（TaskController相关），实现不是很难。 <br />
<br />
如果按客户的方式做，做成功了，其它项目就很好复用，因为它就是做了一个通用的元框架，也算是拿做产品的要求来做项目。 <br />
<br />
另外，如果不做成通用框架，解决现在项目中的若干技术问题难度都不大，如回退、串并行、版本控制、自由流、多子流程、强制跳转、自定义时限、权限控制、流程监控。但&#8220;提供自定义流程功能&#8221;，就是上面客户的要求，这个难度很大，和中棉项目自定义报表难度有的一拼（中棉项目自定义报表以失败告终）。 <br />
<br />
就总结到这儿吧，Workflow、BPM是企业软件的趋势，以后还得努力啊！ <br />
<img src ="http://www.blogjava.net/abram/aggbug/208903.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/abram/" target="_blank">chong</a> 2008-06-18 16:01 <a href="http://www.blogjava.net/abram/articles/208903.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>