在jbpm4.4开发过程中,我们需要使用其提供的接口来完成任务,为什么我们要心甘情愿的被jbpm绑架呢?主要是因为它简单呗……

1.AssignmentHandler

AssignmentHandler是jbpm为我们提供的一个绑定用户,分配任务的接口,我们可以通过实现这个接口来指定Task 的执行者,必须配合jpdl.xml下的标签和程序来使用,web环境下一般都是session中的用户。

举个例子:

一个员工提交一个请假申请,如果我们给这个Task添加一个AssignmentHandler,把员工的姓名绑定进去,那么jbpm就会知道,这个流程是这个员工创建的……

 按正常逻辑请假单已经提交到了领导那,我们可以通过再实现一个AssignmentHandler接口,通过AssignmentHandler动态的对流程实例定义Actor,将领导设置成task的执行者。这样做的好处就是灵活……

当领导登录时,session中是领导的姓名,领导查自己的任务列表就会看到那份员工提交的请假单了。

  • jpdl.xml的一部分(主要是<assignment-handler > 和<decision >两个标签
   
   
   
   
  1.    <task assignee="${name}" g="235,146,92,52" name="LeaveApplication"> 
  2.       <assignment-handler class="com.mtf.jbpm.handler.NewApplicationAssignmentHandler"/> //创建请假单前绑定用户,员工    
  3.       <transition g="-113,-17" name="SubmitApply" to="ManagerApprove"/> 
  4.    task> 
  5.    <task assignee="${name}" g="244,235,92,52" name="ManagerApprove"> 
  6.     <assignment-handler class="com.mtf.jbpm.handler.ManagerApproveAssignmentHandler"/>//当请假单流转到manager那时触发,领导     
  7.       <transition g="-46,-23" name="ManagerApproved" to="DaysCheck"/> 
  8.       <transition g="-15,-35" name="ManagerDisApproved" to="end"/> 
  9.    task> 
  10.     <decision g="67,240,48,48" name="DaysCheck"> 
  11.    <handler class="com.mtf.jbpm.handler.DaysCheckHandler" />   //分支流程
  12.       <transition g="-20,-2" name="LessThan3Days" to="HrMakeSure"/> 
  13.       <transition g="-49,-11" name="MoreThan3Days" to="ExecutiveApprove"/> 
  14.    decision> 
  15.  
  • 申请请假单的AssignmentHandler
   
   
   
   
  1. public class NewApplicationAssignmentHandler implements AssignmentHandler{  
  2.  
  3.     @Override 
  4.     public void assign(Assignable assignable, OpenExecution execution)  
  5.             throws Exception {  
  6.         System.out.println("pxj 创建一leave");  
  7.         String name =(String) execution.getVariable("name");  
  8.         System.out.println(name);  
  9.         assignable.setAssignee(name);    
  10.     }  
  • 领导的AssignmentHandler
   
   
   
   
  1. public class ManagerApproveAssignmentHandler implements AssignmentHandler{  
  2.  
  3.     @Override 
  4.     public void assign(Assignable assignable, OpenExecution execution)  
  5.             throws Exception {  
  6.         System.out.println("经理 开始审批");  
  7.         String id = (String) execution.getVariable("parentId");  
  8.         int managerId = Integer.parseInt(id);  
  9.         EmployeeDao employeeDao = new EmployeeDaoImpl();  
  10.         Employee  e= employeeDao.findEmployeeById(managerId);  
  11.         assignable.setAssignee(e.getE_name_cn());  
  12.     }  

其中parentId是请假单提交的时候设定的,解释一下:员工提交请假单当然是提交到自己领导那了,于是我在提交请假单的方法中查找了一下自己领导的id,存在这个parentId中,到这里面在寻找这个人的姓名(领导的名字)通过assignable.setAssignee(e.getE_name_cn());  将这个Task的执行者设置成领导……于是乎当领导查自己的任务列表时,就能查到自己下属提交的请假单了

  • 这个方法就是提交请假单的方法,应该写在前面才对,思路有些混乱……
   
   
   
   
  1. /**  
  2.  * submitApplication 2012-7-9  
  3.  */ 
  4. @Override 
  5. public void submitApplication(String actorId, float days,  
  6.         ProcessInstance pi, int id) {  
  7.     String taskId = processEngine.getTaskService().createTaskQuery()  
  8.             .processInstanceId(pi.getId()).uniqueResult().getId();  
  9.     // 绑定流程  
  10.     // 寻找上级  
  11.     LeaveDao dao = new LeaveDaoImpl();  
  12.     Leaves leaves = null;  
  13.     try {  
  14.         List all = dao.queryParentById(id, 1);  
  15.         for (int i = 0; i < all.size(); i++) {  
  16.             leaves = all.get(i);  
  17.         }  
  18.     } catch (Exception e) {  
  19.     }  
  20.     System.out.println("TaskId" + taskId);  
  21.     Task tasks = processEngine.getTaskService().getTask(taskId);  
  22.     String executionId = tasks.getExecutionId();  
  23.     processEngine.getExecutionService().setVariable(executionId,  
  24.             "parentId",new String(leaves.getL_emp_id()+""));  
  25.     processEngine.getExecutionService().setVariable(executionId, "days",  
  26.             days);  
  27.     processEngine.getTaskService().completeTask(taskId);  

主要接收:流程实例id,创建人姓名,请假人id,本次总结我只想把jbpm的接口总结一下,关于流程的部分请看下部分。

  • 实际上任务的分配方式有很多种
   
   
   
   
  1. 任务的分类与分配方式  
  2.         任务的分类:  
  3.             个人任务  
  4.                 方式一:指定assignee属性  
  5.                     可以指定为具体的某个String(具体某人);  
  6.                     也可以指定一个流程变量,会使用计算出的结果(结果要是String型)表示办理人。  
  7.                 方式二:  
  8.                     AssignmentHandler中  
  9.                     assignable.setAssignee(userId);  
  10.                 方式三:  
  11.                     processEngine.getTaskService().assignTask(taskId, userId);  
  12.             组任务  
  13.                 方式一:指定candidate-users属性  
  14.                     可以指定为具体的String(多个人之间用英文的逗号隔开);  
  15.                     也可以指定一个流程变量,会使用计算出的结果(结果要是String型,多个人之间用英文的逗号隔开)表示候选人。  
  16.                 方式二:  
  17.                     AssignmentHandler中  
  18.                     assignable.addCandidateUser(userId); // 添加一个组成员(候选人)  
  19.                 方式三:  
  20.                     processEngine.getTaskService().addTaskParticipatingUser(taskId, userId, Participation.CANDIDATE);  

到这里,有关AssignmentHandler的问题都差不多了

2.DecisionHandler

DecisionHandler接口的作用就是根据你给传入的条件进行判断,然后返回一条让你往下继续执行的线,就跟做决定一样。

   
   
   
   
  1. public class DaysCheckHandler implements DecisionHandler {  
  2.     
  3.     @Override 
  4.     public String decide(OpenExecution execution) {  
  5.         //加入判断天数的逻辑  
  6.         String days =execution.getProcessInstance().getVariable("days").toString();  
  7.         float day = Float.parseFloat(days);  
  8.         if(day>3){  
  9.             return "MoreThan3Days";  
  10.         }else{  
  11.             return "LessThan3Days";  
  12.         }  
  13.     }  

获取前面流过来的"days" 然后返回那条线的名字就OK,XML配置见上文,so easy

这两个接口还是比较常用的,我用的方式是比较简单的,但是jbpm比我们想象的灵活多了,尤其是AssignmentHandler,可以加上权限等等,一个实现服务多个用户我觉得应该也是能实现的,唉~~设计模式没学好,晚上继续看!!!