1. 概要
jBPM,全称是Java Business Process Management,是一种基于J2EE的轻量级工作流管理系统。JBPM也是一款非常好的开源工作流引擎。
现在这里从技术角度来分析jbpm的优点和缺点,简单罗列几个大家都容易看见的:
2.优点
a. 自带工作流引擎,思路清晰,编写代码减少;
b. 采用JBPL语言建立工作流程图,可方便查看工作流程图的当前状态。
c. 多种数据库结合使用
d. 可以部署在任何一款JAVA应用服务器上
3. 缺点
a. 与hibernate框架结合相当紧密。
b. 33张系统数据工作流表要自己放到数据库表中。
c. 因加载JBPM多张表故启动速度较慢。
4.学习资料
《JBPM开发指南.pdf》是本非常不错的书籍,大家可以从网上下载该书,该书对大家学习JBPM很有帮助。
5.JBPM工作流实现原理
分三步来操作:
a. 发布JBPM流程文件
b. 启动JBPM流程
c. JBPM流程审批
l 5. 1 发布JBPM流程文件
在JBPM工作流启动流程前,需要先发布JBPM流程文件,而JBPM流程文件中每个流程都
有一个流程定义文件,该文件是采用JPDL语言编写的XML配置文件,在开发工具Eclipse中编写了一个流程定义文件ProcessDefinition.xml(即结点-转向)后,该工具会自动生成一个坐标文件gpd.xml,和一个工作流程图文件processimage.jpg.(注意:该三个文件的名称不可修改)。将该三个文件打包成zip文件,发布JBPM流程文件也就是将zip文件发布。
发布JBPM流程文件的过程需要调用JBPM系统自带的函数来处理。流程文件发布成功后JBPM33个系统数据表将会根据流程定义文件ProcessDefinition.xml来把数据插入到各个JBPM系统表中。
l 5. 2 启动JBPM流程
启动JBPM流程后,系统会自动创建一个流程实例,一个任务实例,一个结点实例,一个令牌实例.系统会将任务开始自动指向流程图的第一个结点.
l 5. 3 JBPM流程审批
JBPM流程审批,会根据已创建的流程实例和结点实例,找到对应的当前任务结点以及该结点对应了多少个转向条件.根据转向条件的不同以及唯一性系统就可以转到下一个相应的结点去审批.
6.搭建基于JBPM的开发环境
采用JBPM技术的项目,需要结合hiberate技术一起使用。
本系统开发的项目采用技术是:struts+spring+hibernate+jbpm。应用服务器为tomcat5.0,数据库采用Mysql4.0。(由于在网上下载的jbpm系统数据33个表的脚本语言都是mysql编写的,如果需要采用数据库为oracle的话,可以下载个转换数据库脚本工具即可)。
l 6.1 jBPM 的下载地址:
http://www.jboss.com/products/jbpm/downloads,下载后的文件是E:/jbpm-starters-kit-3.1.4.
该文件有运行所需要的相关的jbpm的jar包文件以及相关JBPM代码。
l 6.2 在Eclipse中采用JPDL语言建立工作流程图
Eclipse 不是开发 jBPM 必须的工具,但它是对 jBPM 开发很有帮助的工具,特别是 jBPM 提供了一个 Eclipse 插件用来辅助开发jBPM 。
将E:/jbpm-starters-kit-3.1.4/jbpm-designer/jbpm-gpd-feature/eclipse下的文件内容都对应的复制到eclipse相应目录中,这样就可以在Eclipse中用JPDL画工作流程图了.
在Eclipse工作目录上”new”---“other”—“jboss jbpm”----“process definition”来创建三个文件:
gpd.xml,processdefinition.xml,processimage.jpg
JPDL(JBPM Process Definition Language)是JBPM流程定义语言。JPDL详细定义了这个状态图的每个部分,如: 开始、结束状态,状态之间的转换等。这种语言的定义对于用户来说比较容易理解,也比较容易对其进行扩展。
一个JBPM的流程定义XML文件中包含一个< process-definition>元素,而一个< process-definition>元素又包含零个或一个< description>元素,零个或多个的< swimlane>元素,一个< start-state>元素,零个或多个的< state>元素或< decision>元素或< fork>元素或< join>元素,以及零个或多个的< action>元素,零个或多个<task-node>和<node>元素,一个< end-state>元素等等。此外,< process definition>元素有一个标示符,以“name”属性来表示,这个属性必须存在,用来表示该流程的名称。
l 6.3 添加JBPM数据库脚本
从网上下载JBPM的系统自带的33个必备数据表脚本jbpm.sql。该脚本数据库是Mysql。如需要的是oracle数据库,可下载Mysql转oracle工具,就可以转成oracle数据脚本。
33个表相关说明如下:
JBPM_ACTION action记录表
JBPM_DECISIONCONDITIONS 结果条件表
JBPM_DELEGATION 委托表
JBPM_EVENT 事件表 处理进入或者离开事件
JBPM_EXCEPTIONHANDLER 异常处理表
JBPM_ID_GROUP 用户组表
JBPM_ID_MEMBERSHIP 用户成员表 表现用户和组之间的多对多关系
JBPM_ID_PERMISSIONS 用户权限表
JBPM_ID_USER 用户表
JBPM_MODULEDEFINITION 模块定义表
JBPM_MODULEINSTANCE 模块实例表
JBPM_NODE 流程节点表
JBPM_POOLEDACTOR 汇集参与着表
JBPM_PROCESSDEFINITION 流程定义表
JBPM_PROCESSFILE 流程文件表
JBPM_PROCESSFILEBLOCK 流程文件块表
JBPM_PROCESSINSTANCE 流程实例表
JBPM_RUNTIMEACTION 运行中行为表
JBPM_SCRIPTVARIABLES 脚本变量表
JBPM_SWIMLANE 泳道表
JBPM_SWIMLANEINSTANCE 泳道实例表
JBPM_TASK 任务表
JBPM_TASKACTORPOOL 用户行为汇总
JBPM_TASKINSTANCE 任务实例
JBPM_TIMER 计时表
JBPM_TOKEN 令牌表
JBPM_TOKENVARIABLEMAP 令牌变量影射表
JBPM_TRANSITION 转换表
JBPM_VARIABLEINSTANCE 变量实例表
JBPM_VARIABLEINSTANCEBLOCK 变量实例块表
JBPM_VARIABLEMAPPING 变量影射表
l 6.4 相关配置文件
1.将下载的jbpm文件中的jbpm.cfg.xml文件拷贝到工作目录web/web-inf目录中。
2.将下载的jbpm文件中的hibernate.cfg.xml文件拷贝到工作目录web/web-inf/ hibernate.cfg.xml目录中。
3. 流程定义文件也要放在web/web-inf/目录下访问.
4. 打开工作目录下的文件applicationContext.xml,配置相关代码:
l 6.4.1数据库连接池
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost:3306/jbpm?useUnicode=true&characterEncoding=UTF-8</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>password</value>
</property>
</bean>
l 6.4.2 JBPM实例化配置:
<!-- jBPM configuration-->
<bean id="jbpmConfiguration" class="org.springmodules.workflow.jbpm31.LocalJbpmConfigurationFactoryBean">
<property name="sessionFactory" ref="sessionFactory"/>
<property name="configuration" value="WEB-INF/jbpm.cfg.xml"/>
<property name="processDefinitions">
<list>
</list>
</property>
<property name="createSchema" value="false"/>
</bean>
l 6. 5 发布JBPM流程文件
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
//解压zip文件流
String flowdir = (String)theForm.getFlowtype();
FileInputStream fis = new FileInputStream(flowdir);
ZipInputStream zipInputStream = new ZipInputStream(fis);
ProcessDefinition processDefinition = ProcessDefinition.parseParZipInputStream(zipInputStream);
//发布流程文件
jbpmContext.deployProcessDefinition(processDefinition);
jbpmContext.close();
l 6. 6 启动JBPM流程
//得到相应的流程定义,启动流程实例
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
ProcessDefinition processDefinition = jbpmContext.getGraphSession().findLatestProcessDefinition(articleType.getPdName());
ProcessInstance processInstance = new ProcessInstance(processDefinition);
//让流程往下进行一步
Token token = processInstance.getRootToken();
token.signal();
/保存流程实例与状态
jbpmContext.save(processInstance);
jbpmContext.save(token);
jbpmContext.close();
l 6. 7 JBPM流程审批
JbpmContext jbpmContext = jbpmConfiguration.createJbpmContext();
ProcessInstance processInstance = jbpmContext.getProcessInstance(article.getPiId().longValue());
//得到当前的执行令牌
Token token = processInstance.getRootToken();
List transitions = token.getNode().getLeavingTransitions();
Set transitionnames = new HashSet();
if(transitions != null){
for(int i=0; i<transitions.size(); i++){
Transition transition = (Transition)transitions.get(i);
System.err.println("transition.getName()" + transition.getName());
transitionnames.add(transition.getName());//下一节点name
article.setAuditState(transition.getTo().getName()); //下一节点名称
}
}
request.setAttribute("transitionnames", transitionnames);
jbpmContext.close();
String transitionname = request.getParameter("transitionname");
Token token = processInstance.getRootToken();
token.signal(transitionname);
//保存流程实例状态
jbpmContext.save(processInstance);
jbpmContext.save(token);
jbpmContext.close();
http://blog.csdn.net/hitlermen/article/details/4398469