JBPM
? ? ? ? ?JBPM,全称是Java Business Process Management(业务流程管理),它是覆盖了业务流程管理、工作流、服务协作等领域的一个开源的、灵活的、易扩展的可执行流程语言框架。jBPM是公开源代码项目,使用它要遵循 ASL(Apache License Version 2.0)和EULA(JBoss End User License Agreement)协议。
?
?JBPM的运行需要数据库的支持,因此系统设计时要选定所用数据库。
?
这里使用Oracle作为数据库。使用JBPM的版本是?jbpm-jpdl-3.2.3。
?
一、建表空间,建用户
--创建表空间 CREATE TABLESPACE jbpm DATAFILE 'E:\orcl_tblspace\jbpm.DBF' SIZE 10M AUTOEXTEND ON NEXT 32M MAXSIZE UNLIMITED LOGGING EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO; //以分号结束 --创建用户 CREATE USER jbpm IDENTIFIED BY jbpm DEFAULT TABLESPACE jbpm; --把CONNECT、RESOURCE角色授予用户jbpm GRANT CONNECT,RESOURCE TO jbpm
?
三、导入JBPM的表,在jbpm-jpdl-3.2.3/db下找到jbpm.jpdl.oracle,把他导入到新建的数据库用户中,先把该sql文件中的 drop table JBPM_ACTION cascade constraints; 之类语句先删掉。接着,数据库中会多了32张表。
?
?
二、建JavaWeb Project
1.在jbpm-jpdl-3.2.3/config中把如下4个文件复制到新建的JavaWeb?Project中的src目录下。
a.hibernate.cfg
b.jbpm.cfg
c.jbpm.mail.templates
d.log4j.properties
?
2.把jbpm-jpdl-3.2.3/lib中的jar文件做成一个自定义的类库,然后导入到Java Project中。
?
3.导入Oracle的数据库驱动包。
?
4.修改hibernate.cfg配置文件中的dialect、driver_class、url、username和password。
?
5.顺便导入JUnit 4的类库,待会用作测试。
?
6.在JavaWeb?Project中新建一工作流文件夹,例如workflow,用来存放流程图。
?
?
三、新建工作流文件(流程开始时带任务人)
1.
?
2.
?
3.
?
PS:gpd.xml文件可能会报错,不用管,编码问题而已,也不需要打开查看。
?
4.打开processdefinition.xml文件。开始画流程图
?
5.流程图的一些解释。
?
?
6.员工申请报销 流程的设置
Description那里写的是 staff.apply
?
?Assignment是指分派任务,Actor有可以指定作用域或者直接指定人名,例如Jack。
?
7.部门经理审批 的流程设置
Description那里写的是 manager.approve
?
?
这次的分配任务交给一个Java类来处理,选择Handler,这个类要实现AssignmentHandler这个接口。
?
8.财务审批 流程的设置
?
?
?这里也是直接指定财务人。
?
9.通知员工 的流程设置
?
?
?
这里的Actor所指定的角色必须要和 员工申请报销 流程里的Actor所指定的角色一样。
?
10.当设置好流程图的属性的时候,就可以开始部署了。
?
输入一个名字,然后按打开就行了。
?
接着,点击Save Without Deploying... 这个按钮,你就发现你所选择的目录里会多了一个.zip压缩包。
?
11.此时,需要一个Java类,把流程图的属性写入到数据库中
package org.jbpm.util; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import java.util.zip.ZipInputStream; import org.jbpm.JbpmConfiguration; import org.jbpm.JbpmContext; import org.jbpm.graph.def.ProcessDefinition; /** * 部署类 * * @author miao * */ public class DelpoymentUtil { /** * @param args */ public static void main(String[] args) { // 上下文 JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext(); // 该目录是画完流程图之后的部署位置 String url = "C:\\Homework\\JaveSpace\\workStream\\leave.zip"; try { // 输入流 InputStream is = new FileInputStream(new File(url)); // ZipInputStream是InputStream的子类,通过此类可以方便地读取ZIP格式的压缩文件 ZipInputStream zis = new ZipInputStream(is); // 流程定义类 ProcessDefinition pd = ProcessDefinition.parseParZipInputStream(zis); jbpmContext.deployProcessDefinition(pd); zis.close(); is.close(); } catch (Exception e) { e.printStackTrace(); } finally { jbpmContext.close(); } } }
?
运行这个类之后,会在数据库里的?JBPM_TASK 表和?JBPM_TASKINSTANCE 表发现数据。
?
四、编码
做个简单的申请报销处理类
package org.jbpm.process; import org.jbpm.graph.exe.ExecutionContext; import org.jbpm.taskmgmt.def.AssignmentHandler; import org.jbpm.taskmgmt.exe.Assignable; /** * 报销类 * * @author miao * */ public class ApplyProcess implements AssignmentHandler { public void assign(Assignable assignable, ExecutionContext context) throws Exception { // 该名字就是流程图里员工申请报销的那位,通过上下文获取 String name = context.getContextInstance().getVariable("issueperson").toString(); if ("user1".equals(name)) { assignable.setActorId("manager1"); } else if ("user2".equals(name)) { assignable.setActorId("manager2"); } } }
?
?
五、测试类
package org.jbpm.test; import java.util.List; import org.jbpm.JbpmConfiguration; import org.jbpm.JbpmContext; import org.jbpm.context.exe.ContextInstance; import org.jbpm.graph.def.ProcessDefinition; import org.jbpm.graph.exe.ProcessInstance; import org.jbpm.taskmgmt.exe.TaskInstance; import org.junit.BeforeClass; import org.junit.Test; /** * 测试员工报销 * * @author miao * */ public class TestApplyMoney { @BeforeClass public static void setUpBeforeClass() throws Exception { } @Test public void testProcess() { // 1.员工提交申请 submitForm("user1"); // 2.部门经理审核 //managerApprove("manager1"); // 3.财务拨款 //cashierApprove("ali"); // 4.员工领款 //getMoney("user1"); } /** * 1.添加员工提交申请 * * @param actorId */ public void submitForm(String actorId) { JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext(); try { ProcessDefinition pd = jbpmContext.getGraphSession().findLatestProcessDefinition( "applyMoney"); ProcessInstance pi = pd.createProcessInstance(); ContextInstance ci = pi.getContextInstance(); jbpmContext.setActorId(actorId); ci.setVariable("issueperson", actorId); TaskInstance ti = pi.getTaskMgmtInstance().createStartTaskInstance(); ti.end(); } catch (Exception e) { e.printStackTrace(); } finally { jbpmContext.close(); } } /** * 2.部门经理审批 * * @param actorId */ public void managerApprove(String actorId) { JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext(); try { @SuppressWarnings("unchecked") List<TaskInstance> list = jbpmContext.getTaskList(actorId); for (TaskInstance taskInstance : list) { taskInstance.end(); } } catch (Exception e) { e.printStackTrace(); } finally { jbpmContext.close(); } } /** * 3.财务拨款 * * @param actorId */ public void cashierApprove(String actorId) { JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext(); try { @SuppressWarnings("unchecked") List<TaskInstance> list = jbpmContext.getTaskList(actorId); for (TaskInstance taskInstance : list) { taskInstance.end(); } } catch (Exception e) { e.printStackTrace(); } finally { jbpmContext.close(); } } /** * 4.员工领款 * * @param actorId */ public void getMoney(String actorId) { JbpmContext jbpmContext = JbpmConfiguration.getInstance().createJbpmContext(); try { @SuppressWarnings("unchecked") List<TaskInstance> list = jbpmContext.getTaskList(actorId); for (TaskInstance taskInstance : list) { taskInstance.end(); } } catch (Exception e) { e.printStackTrace(); } finally { jbpmContext.close(); } } }
?
每测试一个方法,就会在数据库中的 JBPM_TASKINSTANCE 表看见相应的数据。
?
六、demo(该例子中也包含复杂一点的流程处理,带分支判断,流程开始时不带任务人)
E276-JBPM.zip