理解JBPM(java Business Process Management)的基本概念:
jPDL - JBPM Process Definition Language
JBPM简要过程:
1、定义流程(利用JPDL)
2、部署流程(部署到数据库)
3、创建公文并与流程实例绑定
4、可通过JBPM的接口,触发流程向下流动
5、可通过JBPM的接口,获得流动到某个用户那里的文档(即待处理任务列表)
6、可通过JBPM的接口,结束某个用户的任务(这将触发流程继续向下流动)
7、如此,直到结束
----------------------------------------------
测试:
1、安装JBPM
- 引入Hibernate依赖包
- 引入JBPM依赖包
* bsh.jar
* jcr-1.0.jar
* jbpm-identity.jar
* jbpm-jpdl.jar
- 引入数据库驱动
* mysql-connector-java-3.1.13-bin.jar
2、定义相关配置文件
- Hibernate配置文件
* 提供hibernate配置文件(可以从config/目录下拷贝,并修改其中的数据库连接设置即可)
3、假设现在有一个公文,需要经过:张三、李四、王五的审批之后才能结束
4、我们定义一个Document对象,及其hibernate映射,并将修改hibernate配置文件,将映射添加到其配置中(以便创建相应的数据库表)
Document对象定义如下:
public class Document {
private int id;
private String title;
private String content;
private String creator;
private Long processIntanceId;
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @param id
* the id to set
*/
public void setId(int id) {
this.id = id;
}
/**
* @return the title
*/
public String getTitle() {
return title;
}
/**
* @param title
* the title to set
*/
public void setTitle(String title) {
this.title = title;
}
/**
* @return the content
*/
public String getContent() {
return content;
}
/**
* @param content
* the content to set
*/
public void setContent(String content) {
this.content = content;
}
/**
* @return the creator
*/
public String getCreator() {
return creator;
}
/**
* @param creator
* the creator to set
*/
public void setCreator(String creator) {
this.creator = creator;
}
/**
* @return the processIntanceId
*/
public Long getProcessIntanceId() {
return processIntanceId;
}
/**
* @param processIntanceId
* the processIntanceId to set
*/
public void setProcessIntanceId(Long processIntanceId) {
this.processIntanceId = processIntanceId;
}
}
对应的hibernate配置文件如下:
<hibernate-mapping>
<class table="T_Document" name="org.darkness.jbpmtest.Document">
<id name="id">
<generator class="native"/>
</id>
<property name="title"/>
<property name="content"/>
<property name="creator"/>
<property name="processIntanceId"/>
</class>
</hibernate-mapping>
5、现在让我们来测试一下:
- 创建数据库表: JbpmConfiguration.getInstance().createSchema();
- 定义流程: process.xml
<?xml version="1.0" encoding="UTF-8"?>
<process-definition name="文档测试流程">
<start-state name="开始">
<transition name="提交张三审批" to="张三审批" />
</start-state>
<task-node name="张三审批">
<task name="审批1">
<assignment actor-id="张三" />
</task>
<transition name="提交李四审批" to="李四审批" />
</task-node>
<task-node name="李四审批">
<task name="审批2">
<assignment actor-id="李四" />
</task>
<transition name="提交王五审批" to="王五审批" />
</task-node>
<task-node name="王五审批">
<task name="审批3">
<assignment actor-id="王五" />
</task>
<transition name="结束流程" to="结束" />
</task-node>
<end-state name="结束" />
</process-definition>
- 部署流程:
JbpmConfiguration jbpmConfiguration = JbpmConfiguration
.getInstance();// 创建jbpmConfiguration对象
ProcessDefinition processDefinition = ProcessDefinition
.parseXmlResource("process.xml");// 读取流程定义文件,创建processdefinition对象
// context对象类似于hibernate session对象的功能
JbpmContext context = jbpmConfiguration.createJbpmContext();// 创建jbpmContext对象
try {
context.deployProcessDefinition(processDefinition);// 部署流程到数据库
} finally {
// context对象需要关闭
context.close();// 关闭context对象
}
- 创建公文
Session session = HibernateUtils.getSession();
try {
session.beginTransaction();
Document doc = new Document();
doc.setTitle("测试公文");
doc.setContent("测试公文的内容");
doc.setCreator("赵一");
session.save(doc);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
} finally {
HibernateUtils.closeSession(session);
}
- 将公文与流程绑定(即需要创建流程实例)
JbpmContext context = jbpmConfiguration.createJbpmContext();
context.setSessionFactory(HibernateUtils.getSessionFactory());// 将JBPM与程序中的session绑定
// 从数据库中加载ProcessDefinition对象
ProcessDefinition definition = context.getGraphSession()
.findLatestProcessDefinition("文档测试流程");
// 从流程中创建一个流程实例
ProcessInstance processInstance = new ProcessInstance(definition);
// 存储流程实例
context.save(processInstance);
// 加载公文
Document doc = (Document) context.getSession().load(Document.class, 1);
// 绑定流程实例到公文
doc.setProcessIntanceId(processInstance.getId());
// 绑定公文到流程实例(ContextInstance相当于一个变量的容器)
processInstance.getContextInstance().createVariable("document",
doc.getId());
context.close();
* context.getGraphSession().findLatestProcessDefinition("流程名称");
- 公文创建者提交公文
JbpmContext context = jbpmConfiguration.createJbpmContext();
context.setSessionFactory(HibernateUtils.getSessionFactory());
Document doc = (Document) context.getSession().load(Document.class, 1);// 加载公文信息
ProcessInstance processInstance = context.getProcessInstance(doc
.getProcessIntanceId());// 即根据流程实例ID加载流程实例
// 触发流程往下走(即到达第一个节点)
processInstance.getRootToken().signal();
context.close();
- 这时候,我们可以测试一下,看看流程当前所处的节点
JbpmContext context = jbpmConfiguration.createJbpmContext();
context.setSessionFactory(HibernateUtils.getSessionFactory());
Document doc = (Document) context.getSession().load(Document.class, 1);
ProcessInstance processInstance = context.getProcessInstance(doc
.getProcessIntanceId());
// 当前节点?第一个节点对应的用户登录,应该能够查询到其当前的任务(有公文等待其审批)
System.err.println(processInstance.getRootToken().getNode().getName());
context.close();
查找某个人的任务列表:
List tasks = context.getTaskMgmtSession().findTaskInstances("张三");// 查找张三的任务列表,列表元素是TaskInstance实例
taskInstance.getProcessInstance().getContextInstance().getVariable("document");
通过:可以找到其绑定的公文ID
- 查找到当前的任务对应的公文之后,即可对其审批,并继续往下走
taskInstance.end();
- 如此,直到结束
processInstance.hasEnded()
- 如果流程已经到达终点,本调用将返回true