安装JBPM
- 引入Hibernate依赖包
- 引入JBPM依赖包
* bsh.jar
* jcr-1.0.jar
* jbpm-identity.jar
* jbpm-jpdl.jar
- 引入数据库驱动
定义相关配置文件
- Hibernate配置文件
* 提供hibernate配置文件(可以从config/目录下拷贝,并修改其中的数据库连接设置即可)
定义流程的文档
<process-definition name="文档测试流程"> <start-state name="开始"> <transition name="提交张三审批" to="张三审批"></transition> </start-state> <task-node name="张三审批"> <task name="审批1"> <assignment actor-id="张三"/> </task> <transition name="提交李四审批" to="李四审批"></transition> </task-node> <task-node name="李四审批"> <task name="审批2"> <assignment actor-id="李四"/> </task> <transition name="提交王五审批" to="王五审批"></transition> </task-node> <task-node name="王五审批"> <task name="审批3"> <assignment actor-id="王五"/> </task> <transition name="结束流程" to="结束"></transition> </task-node> <end-state name="结束"></end-state> </process-definition>
POJO实体类
public class Document { private int id; private String title; private String content; private String creator; private Long processIntanceId; }
//在数据库中创建表格
JbpmConfiguration.getInstance().createSchema();
//部署流程
JbpmConfiguration jbpmConfiguration = JbpmConfiguration.getInstance(); JbpmContext context = jbpmConfiguration.createJbpmContext(); try{ context.deployProcessDefinition(processDefinition); }finally{ //context对象需要关闭 context.close(); }
//创建公文
//创建流程实例,将公文并与流程实例绑定
JbpmContext context = jbpmConfiguration.createJbpmContext(); context.setSessionFactory(HibernateUtils.getSessionFactory()); //从数据库中加载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();
获得流程实例对象,并触发流程实例走向下一步
JbpmContext context = jbpmConfiguration.createJbpmContext(); context.setSessionFactory(HibernateUtils.getSessionFactory()); Document doc = (Document)context.getSession().load(Document.class, 1); ProcessInstance processInstance = context.getProcessInstance(doc.getProcessIntanceId()); //触发流程实例走向下一步 processInstance.getRootToken().signal(); //获得当前流程节点的名字 processInstance.getRootToken().getNode().getName() context.close();
第一个节点对应的用户登录,应该能够查询到其当前的任务(有公文等待其审批)
* List tasks = context.getTaskMgmtSession().findTaskInstances("张三"); - 查找张三的任务列表
* 列表元素是TaskInstance实例
* 通过:taskInstance.getProcessInstance().getContextInstance().getVariable("document"); 可以找到其绑定的公文ID
JbpmContext context = jbpmConfiguration.createJbpmContext(); context.setSessionFactory(HibernateUtils.getSessionFactory()); List tasks = context.getTaskMgmtSession().findTaskInstances("张三"); System.err.println("张三的文档有:"); for (Iterator iter = tasks.iterator(); iter.hasNext();) { TaskInstance taskInstance = (TaskInstance) iter.next(); Integer docId = (Integer)taskInstance.getProcessInstance().getContextInstance().getVariable("document"); System.err.println(docId); } List tasks1 = context.getTaskMgmtSession().findTaskInstances("李四"); System.err.println("李四的文档有:"); for (Iterator iter = tasks1.iterator(); iter.hasNext();) { TaskInstance taskInstance = (TaskInstance) iter.next(); Integer docId = (Integer)taskInstance.getProcessInstance().getContextInstance().getVariable("document"); System.err.println(docId); } List tasks2 = context.getTaskMgmtSession().findTaskInstances("王五"); System.err.println("王五的文档有:"); for (Iterator iter = tasks2.iterator(); iter.hasNext();) { TaskInstance taskInstance = (TaskInstance) iter.next(); Integer docId = (Integer)taskInstance.getProcessInstance().getContextInstance().getVariable("document"); System.err.println(docId); } context.close();
- 查找到当前的任务对应的公文之后,即可对其审批,并继续往下走
* taskInstance.end();
JbpmContext context = jbpmConfiguration.createJbpmContext(); context.setSessionFactory(HibernateUtils.getSessionFactory()); List tasks = context.getTaskMgmtSession().findTaskInstances("张三"); for (Iterator iter = tasks.iterator(); iter.hasNext();) { TaskInstance taskInstance = (TaskInstance) iter.next(); //张三已经审批结束,继续提交,这将触发流程继续向下流动! taskInstance.end(); Integer docId = (Integer)taskInstance.getProcessInstance().getContextInstance().getVariable("document"); System.err.println(docId+"已被审批完成"); }
- 如此,直到结束
* processInstance.hasEnded() - 如果流程已经到达终点,本调用将返回true
//部署流程定义 getJbpmContext().deployProcessDefinition(pdf); //删除流程定义 List defs = getJbpmContext().getGraphSession().findAllProcessDefinitionVersions(workFlow.getName()); for (Iterator iterator = defs.iterator(); iterator.hasNext();) { ProcessDefinition pdf = (ProcessDefinition) iterator.next(); getJbpmContext().getGraphSession().deleteProcessDefinition(pdf); } //创建流程实例,先根据流程定义的名称获得流程定义对象,获得流程定义(GraphSession对象) GraphSession graphSession = context.getGraphSession(); //findLatestProcessDefinition查找最新的流程定义,根据流程名称 ProcessDefinition process = context.getGraphSession().findLatestProcessDefinition(workFlowName); ProcessInstance instance = new ProcessInstance(process); //绑定到文档,根据文档的ID instance.getContextInstance().createVariable("documnet", documentId); context.save(instance); //删除流程实例 context.getGraphSession().deleteProcessInstance(processInstanceId); //获得一个流程实例,根据ID ProcessInstance processInstance = jbpmContext.getProcessInstance(doc.getProcessIntanceId()); //获量(TaskInstance)流程实例的数组(根据用户名字) List task = context.getTaskMgmtSession().findTaskInstances(username); for (Iterator iterator = task.iterator(); iterator.hasNext();) { TaskInstance taskInstance = (TaskInstance)iterator.next(); //是否 if(!taskInstance.isSignalling()){ continue; } //先获得ProcessInstance,再获得ContextInstance,再getVariable,(创建的时候是setVariable) //得到的是文档的ID Integer i = (Integer) taskInstance.getProcessInstance().getContextInstance().getVariable("document"); docIds.add(i); } //获得当前节点和起始节点 String currentNodeName = instance.getRootToken().getNode().getName(); String startNodeName = instance.getProcessDefinition().getStartState().getName(); /** * 搜索下一步的流向,即下一步都可以走哪些路径 * Parameters: * username * processInstanceId * Returns: * 流向的名称列表 */ public List searchNextTransitions(String username, long processInstanceId) { JbpmContext context = getJbpmContext(); List transitions = new ArrayList(); ProcessInstance instance = context.getProcessInstance(processInstanceId); String currentNodeName = instance.getRootToken().getNode().getName(); String startNodeName = instance.getProcessDefinition().getStartState().getName(); Collection nextSteps = null; //如果当前节点和起始节点相等 if(currentNodeName.equals(startNodeName)){ //获得走向的Set集合 nextSteps = instance.getRootToken().getAvailableTransitions(); }else{ //如果当前节点不是起始节点,获得用户的TaskInstance List list = context.getTaskMgmtSession().findTaskInstances(username); for (Iterator iterator = list.iterator(); iterator.hasNext();) { TaskInstance taskInstance = (TaskInstance) iterator.next(); //如果相等,获得走向的Set集合 if(taskInstance.getProcessInstance().getId()==processInstanceId){ nextSteps = taskInstance.getAvailableTransitions(); break; } } } //只获得名字 for (Iterator iterator = nextSteps.iterator(); iterator.hasNext();) { Transition transition = (Transition) iterator.next(); transitions.add(transition.getName()); } return transitions; } //流向下一步 public String flowToNextStep(String username, long processInstanceId, String transitionName) { JbpmContext jbpmContext = getJbpmContext(); String status = null; ProcessInstance instance = jbpmContext.getProcessInstance(processInstanceId); String currentName = instance.getRootToken().getNode().getName(); String startName = instance.getProcessDefinition().getStartState().getName(); if(currentName.equals(startName)){ //起始节点,流向指定的transitionName instance.getRootToken().signal(transitionName); }else{ List task = jbpmContext.getTaskMgmtSession().findTaskInstances(username); for (Iterator iterator = task.iterator(); iterator.hasNext();) { TaskInstance taskInstance = (TaskInstance) iterator.next(); if(taskInstance.getProcessInstance().getId()==processInstanceId){ //非起始节点,流向指定的transitionName taskInstance.end(transitionName); break; } } } //获得当前的Token status = instance.getRootToken().getName(); if(instance.hasEnded()){ status = Document.STATUS_END; } return status; }