原文出自: http://www.cnpoint.com/framwwork/2006/1027/content_4504.htm
jBPM
开发整理
1. 概述
jBPM是一个工作流平台,它实现了一系列的基础类,提供了面向图形编程的方式来定义流程,方便用户在此基础上专注业务流程逻辑的实现;他依赖很少的库文件,能很好地嵌入到已有的Java Project当中。
jBPM采用Hibernate进行数据持久化的管理;
一般的开发流程为:
1.选定数据库,对数据库进行初始化;jBPM平台本身需要数据库的支持,
所以在使用jBPM之前要先初始化相应的数据库,包括创建表和插入初始
化数据等。
2.使用JBPM定义流程,生成ProcessDefinition.xml;并加入自定义的处理代码,如Action等。
3.利用JUnit Framework写单元测试。
4.部署jBPM。
2. 环境配置
2.1 Eclipse
1.为了支持图形化的流程定义,安装jBPM图形化插件,位置为:
/jbpm-starters-kit-3.1.1/jbpm-designer/jbpm-gpd-feature/eclipse
2.2 Library
1.JBPM 3 要求 J2SE 1.4.2 +
2.JBPM库:
jBPM核心功能库:jbpm-[version].jar (位于jbpm/build下)
jBPM可选的身份验证库:jbpm-[version].jar(位于jbpm/build下)
3.必须的第三方库:(位于jbpm/lib下)
XML分析库:dom4j-1.6.1.jar
Logging库:commons-logging.jar
4.可选的第三方库:
见User Guide Chapter 5
2.3 Configuration Files
Table 2-1 Configuration Files
路径
|
作用描述
|
src/config.files/jbpm.cfg.xml
|
配置jBPM参数
|
src/config.files/hibernate.cfg.xml
|
配置Hibernate连接参数等
|
org/jbpm/db/hibernate.queries.hbm.xml
|
定义了Hibernate的常用查询Query
|
org/jbpm/graph/node/node.types.xml
|
Node类型和对应实现类的映射
|
org/jbpm/graph/action/action.types.xml
|
Action类型和对应实现类的映射
|
org/jbpm/calendar/jbpm.business.calendar.properties
|
定义了Business Hour和Free Time
|
org/jbpm/context/exe/jbpm.varmapping.xml
|
定义了使用何种类完成某种Java对象转换为jBPM中可存储的数据库实例
|
org/jbpm/db/hibernate/jbpm.converter.properties
|
定义了ID和Class Name的映射
|
org/jbpm/graph/def/jbpm.default.modules.properties
|
定义了创建ProcessDefinition时,缺省加载的模块
|
org/jbpm/jpdl/par/jbpm.parsers.xml
|
定义了分析器
|
3. 开发步骤
3.1创建jBPM项目
1.在Eclipse中创建一个Process Project项目
3.2 配置数据库
1.下载PostgreSQL、pgAdmin和dbVisualizer
Account:qlisguo/leesen;SuperUser:postgres/leesen127
2.创建JbpmDB数据库;
3.运行jbpm-db/build/postgresql/scripts/postgresql.create.sql,为jBPM创建
初始化的表、索引等;
4.可选:为了让jBPMStarterKit自带的WebApp能运行,必须对
jbpm_id_user初始化,加入一些帐号;
5.可选:为了让jBPMStarterKit自带的WebApp运行,必须修改已部署的
JBoss的配置文件,配置数据源;
6.修改jbpm 项目中Hibernate的数据库连接配置文件Hibernate.cfg.xml;
3.3 流程定义
1.在Processes目录下创建一个ProcessDefinition Project;
2.利用图形化界面对ProcessDefinition.xml进行业务逻辑流程的定义;
3.4 JUnit测试
1.src/java.jbpm.test 是StarterKit 自带的测试用例
2.继承junit.framework.TestCase类
3.jBPM工作流的测试流程
3.5 部署
4. jBPM 流程整理
创建ProcessDefinitionà创建ProcessInstanceàToken.signal() ;
一个Process Definition即是一张有向图,由Node和Transition完成流程的执行。
Token:
·
是一个链表结构,具有唯一的父Token和若干子Token;每个Token都包含一个Node节点指针;这意味着,Token链表表示了一条流程的执行路径。
·
当一个ProcessInstance被创建时,一个rootToken同时被创建。
·
Token.signal()方法调用 Node.leave(),Node.leave() 设置Token的当前Node为新的Node,从而让流程继续下去。其执行路进如下所示:
Token.signal()
àNode.leave()
àTransition.take()
àNode.enter()
àNode.execute()
·
当Token进 入一个Node时,该Node的execute方法即被调用,每个Node都可以在execute()方法中定义自己的流程执行方式。而 State 类型的Node是不会传播执行的,即当Token进入State Node时,只能通过Token.signal()方法,显式地去让流程继续。
Node:
·
Node有 两个责任:1)执行纯java代码,比如创建Task,更新数据库等;2)负责传播执行流程:不传播(内置的Node Type中只有State Node不传播);自动选择一条Leave Transition,继续流程;创建新的执行路径即新的Token(例如Fork Node);结束流程;更改流程执行时的结构,即Token Tree。
·
每种Node Type 都重载了Node 类的execute方法,其中只有State Node的execute()方法为空,即意味着当Token进入State Node时,流程即停止在此。
Node Type
|
Description
|
Task Node
|
当流程进入该Node时,该Node会创建一系列的Tasks;然后等待这些Tasks完成;当Tasks完成之后,则会调用token.signal()方法,使流程自动执行下去。
|
State
|
要显示调用token.signal()方法,才能使流程继续
|
Actions:
5. jBPM APIs 整理
5.1 ProcessDefinition
里面包含Node,Tasks,Swimlane,Transition等的定义,可以利用getXXX方法获得其中的元素。
ProcessDefinition processDefinition = ProcessDefinition.parseXmlString(
"<process-definition>" +
" <task-node name='saturday afternoon'>" +
" <task name='wash car'>" +
" <assignment class='the-wash-car-assignment-handler-class-name' />" +
" </task>" +
" </task-node>" +
"</process-definition>"
);
5.2 Configuration、Context
bpmConfiguration jbpmConfiguration = JbpmConfiguration.parseResource("org/jbpm/jbpm.test.cfg.xml");
jbpmContext = getJbpmConfiguration().createJbpmContext();
从jbpmContext中可以获得所有的session,例如getGraphSession()…
5.3 ContextInstance 操作变量
·
org.jbpm.module.exe.ModuleInstance.ContextInstance 类负责对变量进行操作。
·
获取一个ContextInstance:
ContextInstance contextInstance = (ContextInstance) processInstance.getInstance(ContextInstance.class);
·
Variables的 持久化是伴随JbpmContext的save(ProcessInstance)方法的,因为Variables是ProcessInstance的一 部分;如果有不想持久化的Variable的话就利用ContextInstance.setTransientVariable(),创建临时变量。
5.4 org.jbpm.context.log 变量日志管理
·
记录的Variable的更新,删除,创建等日志
5.5 Task 任务管理
·
TaskMgmtDefinition管理Task所和Swimlane
taskMgmtDefinition = processDefinition.getTaskMgmtDefinition();
processDefinition = new ProcessDefinition();
taskMgmtDefinition = new TaskMgmtDefinition();
processDefinition.addDefinition(taskMgmtDefinition);
buyer = new Swimlane("buyer");
laundry = new Task("laundry");
dishes = new Task("dishes");
·
TaskNode à Task à TaskControlleràVariableAccess 层次关系。
TaskController.submitParameters()方法,可以把TaskInstance的Task Variable新值更新到对应的Process Variable;
·
TaskMgmtInstance 运行时的任务管理
TaskMgmtInstance tmi = (TaskMgmtInstance) processInstance.getInstance(TaskMgmtInstance.class);
·
TaskInstance可以调用set/getVariable()方法,对Task的Local变量进行存取
·
TaskMgmtInstance.createStartTaskInstance(),创建start state 中的任务,并把该任务分派给当前的Actor。
5.6 Swimlane的整理
1.Swimlane是task的role。Tasks可以分配给swimlane,同时users、group也可以被指派到swimlane,通过 swimlane这作桥梁,tasks就被分配给了特定的users。 需要注意的是,swimlane不包含授权控制,即如果user A 没有通过swimlane分配到task A,user A仍然可以通过 task.end()来结束任务。
5.7 Token 的整理
1.当创建一ProcessInstance时,自动创建了一rootToken
2.当rootToken 进入Fork Node 时,就会自动根据Transition 名创建子Token(/TransitionName),而rootToken则在Fork Node处等待,通过ProcessInstance.findToken()找到子Token继续分支流程的完成,待所有的分支流程完成,则 rootToken被自动激发到 Join Node 的下一个节点。分支流程的token起始指向的Node就是ForkNode对应的 Transition to的节点。
3.Decision Node 根据指定的Decision Handle ,来决定选择哪一条transition。