JBPM4 学习使用总结
jBPM是一个灵活的业务流程管理(BPM)套件。它是不懂技术的业务人员和开发人员之间的桥梁。传统的BPM引擎只关注业务人员,而jBPM集BPM和工作流于一体,因此它有更大的应用场景和应用人群。
这几天趁有点时间,学习了下JBPM,主要是在应用方面,用的是目前JBPM的最新版本是4.3。
一、先决条件
环境:JDK5,Maven 2.2.1
Maven其实可以不用的,因为JBPM的SDK中已经包含了所有开发需要的jar包,但是为了用Maven管理项目,后面的jar包都是从Jboss的库的下载的。
JBPM SDK:http://sourceforge.net/projects/jbpm/files/
数据库(MySQL),由于JBPM4使用Hibernate来实现数据访问操作的,所以只要是Hibernate支持的数据库,在JBPM4中都能支持。
二、新建Maven工程,修改pom.xml文件
1、增加JBPM4的jar包依赖
<!-- JBPM 4 -->
<dependency>
<groupId>org.jbpm.jbpm4</groupId>
<artifactId>jbpm-api</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.jbpm.jbpm4</groupId>
<artifactId>jbpm-jpdl</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.jbpm.jbpm4</groupId>
<artifactId>jbpm-pvm</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.jbpm.jbpm4</groupId>
<artifactId>jbpm-bpmn</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.jbpm.jbpm4</groupId>
<artifactId>jbpm-log</artifactId>
<version>4.3</version>
</dependency>
<dependency>
<groupId>org.jbpm.jbpm4</groupId>
<artifactId>jbpm-db</artifactId>
<version>4.3</version>
<exclusions>
<exclusion>
<groupId>hsqldb</groupId>
<artifactId>hsqldb</artifactId>
</exclusion>
<exclusion>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</exclusion>
<exclusion>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
</exclusion>
</exclusions>
</dependency>
2、增加其它jar包依赖
<!-- Spring Framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>2.5.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-modules-validation</artifactId>
<version>0.9</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>2.5.6</version>
</dependency>
<!-- MySQL JDBC -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.2</version>
</dependency>
<!-- Logging -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.14</version>
</dependency>
<!-- Commons API -->
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.5</version>
</dependency>
<dependency>
<groupId>commons-collections</groupId>
<artifactId>commons-collections</artifactId>
<version>3.1</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>commons-pool</groupId>
<artifactId>commons-pool</artifactId>
<version>1.3</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.apache.ibatis</groupId>
<artifactId>ibatis-sqlmap</artifactId>
<version>2.3.4.726</version>
</dependency>
<dependency>
<groupId>xerces</groupId>
<artifactId>xercesImpl</artifactId>
<version>2.9.1</version>
</dependency>
<!-- Velocity -->
<dependency>
<groupId>org.apache.velocity</groupId>
<artifactId>velocity</artifactId>
<version>1.6.3</version>
</dependency>
<dependency>
<groupId>org.apache.velocity.tools</groupId>
<artifactId>velocity-tools</artifactId>
<version>2.0-alpha1</version>
</dependency>
<!-- Servlet API -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>test</scope>
</dependency>
<!-- test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.4</version>
<scope>test</scope>
</dependency>
3、增加JBPM的Maven库
<repositories>
<repository>
<id>repository.jboss.org</id>
<url>http://repository.jboss.org/maven2</url>
</repository>
<repository>
<id>repository.jboss.com</id>
<url>http://repository.jboss.com/maven2</url>
</repository>
</repositories>
4、构建eclipse工程
mvn eclipse:eclipse
说明:如果不用Maven管理工程,可以向工程加入下载下来的JBPM SDK的lib目录中的所有jar包。
三、建立数据库(MySQL)表结构
1、建数据库(jbpm)
/* 建立数据库 */
drop database jbpm;
create database jbpm;
/* 设置编码 */
alter database jbpm characterset GBK;
use example;
/* 用户授权 */
grant all privileges on jbpm.* to jboss@"%" identified by'jbpm';
grant all privileges on jbpm.* to jboss@"localhost" identified by'jbpm';
运行以下的SQL后,可以得到信息:
数据库名:jbpm
数据库编码:GBK
用户名/密码:jboss/jbpm
2、建数据表
导入:${JBPM_SDK}/install/src/db/create/jbpm.mysql.create.sql
这样,数据库jbpm中一共有18张数据表了,这18张表是运行JBPM所需的全部数据表。
四、配置文件及与Spring的集成
1、JBPM核心配置文件:jbpm.cfg.xml
<?xml version="1.0" encoding="GB2312"?>
<jbpm-configuration>
<import resource="jbpm.default.cfg.xml" />
<import resource="jbpm.tx.spring.cfg.xml" />
<import resource="jbpm.jpdl.cfg.xml" />
<import resource="jbpm.bpmn.cfg.xml" />
<import resource="jbpm.identity.cfg.xml" />
<import resource="jbpm.businesscalendar.cfg.xml" />
<import resource="jbpm.console.cfg.xml" />
<!--
<import resource="jbpm.jobexecutor.cfg.xml" />
-->
<process-engine-context>
<string name="spring.cfg" value="aboyJbpmApplication.xml" />
</process-engine-context>
</jbpm-configuration>
与Spring的集成的集成全在aboyJbpmApplication.xml中了。
2、其它的配置文件内容
数据源,Hibernate的sessionFactory,注意的是与Spring集成后,JBPM的处理引擎可以通过工厂方法取得。
<bean id="springHelper" class="org.jbpm.pvm.internal.processengine.SpringHelper" />
<bean id="processEngine" factory-bean="springHelper"
factory-method="createProcessEngine" />
五、测试发布一个流程
1、新建一个流程(HelloWorld.jpdl.xml)
流程三个状态:开始à确认à完成
<?xml version="1.0" encoding="UTF-8"?>
<process name="HelloWorld" xmlns="http://jbpm.org/4.3/jpdl">
<start g="16,19,48,48">
<transition to="receive confirmation" />
</start>
<state name="receive confirmation" g="96,16,136,52">
<transition to="end" />
</state>
<end name="end" g="269,20,48,48"/>
</process>
2、发布测试该流程(HelloWorldTest.java)
@Test
publicvoid testProcess() {
ProcessEngine processEngine = Configuration.getProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
Assert.assertNotNull(repositoryService);
String deploymentID = repositoryService.createDeployment().addResourceFromClasspath("HelloWorld.jpdl.xml").deploy();
repositoryService.deleteDeploymentCascade(deploymentID);
}
3、ProcessEngine的七(6+1)个核心服务
六个显示服务:
RepositoryService:流程定义的服务接口,包括对流程定义的部署、查询、删除操作;
ExecutionService:流程执行的服务接口,包括启动流程、实例推进、设置变量等操作;
TaskService:人工活动的服务接口,包括对任务的创建、提交、查询、保存、删除等操作;
ManagementService:Web管理控制台的服务接口,包括获得消息和计时器的操作;
HistoryService:历史库的服务接口,包括对流程实例、活动实例进行查询、某个流程定义中的所有活动的平均持续时间、某个流程定义中的某个活动实例的转移的执行次数等操作;
IdentityService:主要包括用户、组、成员关系等相关操作。
一个隐式服务:
CommandService:Command模式的服务接口,实际上就是将客户端的请求全部封装在一个调用接口中,然后由这个接口去调用Command接口的众多实现(StartExecutionCmd、SignalCmd、SetVariablesCmd、GetTimersCmd、DeployCmd、NewTaskCmd、SubmitTask、ExecuteJobCmd)。因为在ProcessEngine中并没有提供取得CommandService的方式,只是提供了execute(Command cmd),其实现其实是调用CommandService。
六、疑问和解决
1、JBPM4如何与日常的工作流程对应起来(申请à审核à结束)?
制定流程(可能由组织内多人协商决定)ßà编写流程定义文件(流程名.jpdl.xml);
宣布流程(可以在网站上进行申请了)ßà发布流程(RepositoryService);
申请(填写申请表单)ßà启动流程(ExecutionService),此时流程的状态为“申请“,即等待用户提交表单;
申请(提交申请表单)ßà结束申请任务(TaskService),此时流程的状态为“审核“,即A已经申请了,A的任务已经完成了,等待B来审核;
审核(提交审核信息)ßà结束审核任务(TaskService),此时流程已经结束,所有人(A和B)的任务已经完成。
2、不同版本的流程是否可以共存?
可以共存,在发布流程时,JBPM根据流程的Key来做版本控制,在查询时,可以根据Key查询,也可以根据Id查询。
3、在结束一个任务(或是推进流程)时,ExecutionService.signalExecutionById和TaskService.completeTask的区别?
这两个方法都是在推进流程,它们的使用场景有所不同。应用场景分两种:人为的操作和外部系统。
需要人的操作用Task,当人完成任务后,流程不再等待,流程继续;
不需要人的操作,系统与系统之间的互发信息,用Signal,当一个系统收到一个信号后,结束等待,流程继续。
如果在Task活动中让流程等待,直接使用signal,流程就会继续向下执行,任务就会与流程不同步(任务未完成,流程先走),完成任务时,要么找不到对应的流程,要么会让流程错误的继续执行。
应用场景:一个流程执行到某个state,向外部财务系统发送请求付款的消息,然后进入等待状态,当外部财务系统完成付款后,会根据流程id调用流程引擎的 signal,让流程继续向下推进。
如果流程需要等待一个操作人员来处理事务,处理之后让流程继续执行,就用task给这个人发送一个任务,告诉这个操作员要做一些事情,操作员完成事务之后,点击completeTask,流程就继续向下运行。
参考资料
1、 Jboss Jbpm用户手册:http://docs.jboss.com/jbpm/v4/userguide/html_single/
2、 JavaEye的JBPM圈子:http://jbpm.group.iteye.com/
3、 “贩卖你168“论坛”一起学习jBpm“版块:http://old.family168.com/bbs/index.asp?boardid=6
4、 搜索引擎百度:http://www.baidu.com和谷歌:http://www.g.cn
5、 Jboss Jbpm官网:http://www.jboss.org/jbpm
6、 Jboss Jbpm社区:http://community.jboss.org/en/jbpm?view=discussions
-----------------------------------
JavaEye竟然不能插入Word文档内容,只好以附件的形式给出了。
上一篇: PHP里面如何用try…catch