当前我指的JBPM是3.2版本,因为从JBPM2.0到3.0,其API从package到class都完全重新设计了,以及其背后的建模思想和架构。
在2.0版本里,是按照Spring+Hibernate那种Transaction
Script方式组织的,OO的概念比较弱,里面是大量的interface、impl、service。而3.0版本,完全按Domain
Model方式组织,Hibernate透明持久化,它是我见到的O/R Mapping最优雅的应用。
在当前的3.2版本里,其整体架构可以这么去理解:领域对象,如ProcessDefinition、ProcessInstance、
Node、Token、Transition等,都是Rich
Model,里面的方法主要是处理业务,以及建立领域对象之间的关联,持久化则完全放在XXXSession中,如
TaskMgmtSession,GraphSession等,也可以认为这些XXXSession是DAO,负责处理持久化。另
外,org.jbpm.persistence.db.DbPersistenceService这些类相当于最底层的数据库Helper类。总
之,JBPM的技术架构非常清晰易懂,也是非常典型的Domain Driven Design,在这种架构中,分层的概念被弱化了。
上面是从架构的角度看待JBPM设计,其引擎设计和实现,则隐藏在架构下。了解其引擎设计思想,我的建议是,先仔细读读JBPM的User
Guide第四章Graph Oriented
Programming,专门探讨流程建模的理论,里面附带了一个微型的JBPM实现,几乎包括流程建模的绝大部分,如顺序流、并行、分支等:http://docs.jboss.com/jbpm/gop/jbpm.gop.zip
,我建议研读JBPM源码前,先把这个理解透,JBPM的流程引擎核心代码和它非常相似,包括类名,只是扩展了一些。
我用代码统计工具统计了一下,JBPM源码总共4w多行,除去注释和空行,约2万6千行。需要我们hack的核心、比较难、代码多的类约40个
(共400多),反正它花了我整四天的时间,现在基本都弄清楚了。我主要是通过一个请假流程的部署、创建、任务执行来动态debug、静态查看的。
JBPM源码中最难读懂的那部分是引擎调度,也就是org.jbpm.graph相关的几个包,最重要的是GraphElement和其子类
Transition等、Node及其子类Fork等、ExecuteContext和Token。而引擎调度这部分,
JBPM附带了一个微型JBPM实现,我在前面介绍过。除了引擎调度,其它相关源码就非常简单了。
在JBPM中,有很多API是供JBPM自身调用的,如流程定义文件中支持的Expression语言,脚本等(org.jbpm.jpdl.el.impl),我们不用理会。
我们主要和下面三类API打交道:
JBPM环境的配置、service的管理、流程的部署和卸载:
它主要体现在org.jbpm中,另外辅助包有org.jbpm.jpdl.xml、org.jbpm.configuration。
org.jbpm.configuration负责services对象的创建,相当于一个微型的IoC容器、对象工厂,负责services的
生命周期管理,如加载、创建、调用和销毁,像Job调度服务、数据库持久化服务、异步消息服务等。需要说明的是,由于其package下的
ObjectFactoryImpl也是一个IoC容器,和Spring的IoC容器是有相同的职责:对象的管理。所以在这种松耦合架构下,可以将
JBPM和Spring集成,如业务系统和JBPM引擎的事务处理、对象管理、配置管理等。请参考Spring-Module开源项目。
org.jbpm.jpdl.xml负责流程定义文件的解析,譬如XML文件的解析,相关领域对象的实例化。通过hack其源码和原理,我们可以在业务系统中自定义流程,让用户可以自己定义、变更流程。
JBPM中领域对象:
如Node、Token、ProcessInstance、TaskInstance
等,它们有三个职责,一个是保持从DB中加载流程和任务相关的数据或将数据持久化到DB。第二,为各领域对象建立关联,方便实现透明持久化(复杂的领域关
联在Hibernate的mapping文件里配置)。第三,就是处理业务规则,如引擎调度算法,但不负责持久化。
JBPM中持久化领域对象的Manager,DAO:
如TaskMgmtSession。它们主要是持久化领
域对象,如session.save(ProcessInstance);或是执行查询,如根据流程ID查询该流程实例,查询操作都是配置在
hibernate
mapping中的hql语句,如hibernate.queries.hbm.xml。但可能并不能满足我们的要求,譬如按时间段查询当前的流程实例,
任务的分页查询,这样,就需要我们自己扩展这些DAO类。由于它们查询是只读操作,所以很容易,而且扩展几乎是必然了,因为要是按JBPM默认的,把所有
的Result查询出来,再过滤,性能是个很大的问题,我们应该按需查询。
--------------------------------------
下面按功能分类说明一下:
JBPM流程的部署和卸载
JBPM流程的部署和卸载,无论是通过管理控制台还是自定义部署,最终都是通过JbpmContext的
deployProcessDefinition(ProcessDefinition)部署,而ProcessDefintion实例的创建,是通过调
用ProcessDefinition的相关方法,如parseXmlResource (String xml)。
ProcessDefintion实例的创建,有多种输入源,譬如XML字符串、XML文件、zip包,还有最抽象的Reader、
InputStream。如果在用户的业务系统里面自定义发布业务流程,也最终是调用ProcessDefinition相关方法。但流程定义解析,最核
心的只有一个类:org.jbpm.jpdl.xml包下的JpdlXmlReader,
org.jbpm.JbpmContext:该类可以理解为Façade模式的实现,与流程相关的manager类可以通过它取得,如
getGraphSession()、getServices(),它是获取其它服务的快捷方式,也算是一个delegate类。如果大家对
Context的概念比较敏感,其类职责就很好理解,在Servlet容器里面也有ServletContext的概念,和它意思差不多。对一般的系统软
件一般来说,Context往往建模成Container的上下文。在JBPM中,它还负责流程部署、加载、卸载。
JBPM的任务管理
JBPM和任务管理相关的类主要是org.jbpm.taskmgmt.def和org.jbpm.taskmgmt.exe,像任务创建、分配等。
和任务相关的最重要的有两个方面,一个是任务分配,另一个是和任务相关的表单。当然,任务查询和任务日志也很重要。
任务分配:解决的是将任务分配给谁,它有静态分配和动态分配两种,前者是在流程定义文件里部署,后者是通过代码动态指定。它涉及到的概念有
Actor,PooledActor,Swimlane,AssignmentHandler。在做demo时,譬如JBPM官方自带的例子
webSale里,就是通过Expression静态部署任务角色的,如user(leo),group(orderManager),但它用到了
JBPM的第三方组件Identity,其实通过Expression静态分配角色,本质上也是通过AssignmentHandler实现的,如
ExpressionAssignmentHandler。
任务分配,一般比较灵活的方案是在流程的Swimlane里面部署自定义action,然后重用swimlane。另外一种方案是,在每个task里面部署AssignmentHandler实现类。
任务相关表单:主要是org.jbpm.taskmgmt.def.TaskController,它是task
scope下的表单字段,类似Servlet里面的HttpServletRequest的setAttribute()。如果是process
scope下的表单项,是org.jbpm.context.exe.ContextInstance,类似于Servlet里面的
HttpSession的setAttribute()。
附带说一下任务查询,所有有关查询和持久化的操作,都集中在包org.jbpm.db中,如任务相关的TaskMgmtSession,要是这些find方法不满足业务要求,建议自己扩展。
JBPM的流程日志
JBPM的流程日志,主要是记录一些事件(Event),如流程创建、任务分配,它们在GraphElement的fireEvent时,譬如在
Node.leave()(Token离开当前节点时)触发fireEvent事件(在该事件方法里执行自定义Action),同时记录日志。我们关心的
日志主要有process、task、transition、signal四类,每个下面还有事件细分,如task创建和分配。通过日志,我们统计流程执
行效率,也可以得到详细的流程步骤日志。
日志的查询,请参考LoggingSession及其相关类。顺便说一下,所有的日志类都继承于ProcessLog,约20来个。JBPM已经声明的日志查询方法,可能并不能满足我们的要求,自行扩展吧。
其它API
JBPM
API里有org.jbpm.web、org.jbpm.security等,前者负责在web容器启动时加载JBPM引擎,将当前Session的用户
设置为任务的Actor等,后者负责安全相关的认证和授权。源码很简单,不多说了。我建议实现类似业务需求时,不妨参考其实现,但拿来用就会发现它太简陋
了。
分享到:
相关推荐
jBPM源码分析jBPM源码分析jBPM源码分析jBPM源码分析
jbpm4源码jbpm4源码jbpm4源码
JBPM源码分析 JBPM源码分析:讲解各个类之间的关系与代码
NULL 博文链接:https://kennethlau.iteye.com/blog/1440630
通过jbpm源码分析jbpm引擎内核工作原理
jbpm项目项目源码项目源码项目源码项目源码项目源码
JBPM4.0源码以及分析,对PVM和JPDL进行了扩展
jbpm开发源码,一个jbpm开发的小例子
jbpm4.2 src(JBPM源码) 欢迎下载。。。。
jbpm 源码 src source 111111111111111111
用于开发JBPM的一些源码以及相应的帮助文档
jbpm4.4项目测试源码下载, 效果图请看:http://blog.csdn.net/liangrui1988/article/details/11907459
,jbpm4的源码,分支,会签等一些中国特色建立下载《jBPM4工作流应用开发指南.pdf》这本书
传智播客汤阳光JBPM3源码,这是本人对照汤阳光OA项目视频自己手工编写的代码
完整的JBPM实例详细精讲,可下载运行调试通过。最快,最有成效上手的实例。也可保存作为以后学习参考的源码,操作指导。谢谢。
资源共享 jbpm使用的举例,值得初学者一看;
jbpm3.2.3一个简单的流程例子,只要把数据库弄好就可以运行了
Jbpm与ssh2的集成的环境搭建,只是简单的搭建,有分层,可以从spring中取到processEngine
jbpm流程引擎框架源码,一套流行的流程引擎框架代码
包括jpdl,jbpm-console,jbpm-bpel