工作流引擎调用业务逻辑

来源:互联网 发布:mac最大化窗口的快捷键 编辑:程序博客网 时间:2024/05/18 03:48
在基于工作流进行业务系统开发时,通常需要在某些事件发生时或某些情况下,由低层工作流引擎调用上层的业务处理逻辑,比如在示例业务需求中,当部门主管审批员工请假申请时,审批事件发生时需要将审批意见插入到数据库表中,并进入后续相应的步骤,这里的将审批意见插入数据库,可以在业务程序中审批处理代码中直接插入,也可以只让审批处理代码只负责调用工作流引擎的“审批处理”步骤的doAction,而在doAction的过程中由引擎调用插入数据的操作;又例如在某些动作执行后向用户发送邮件通知。

这样当采用由引擎调用业务处理后,就可以在不改变程序代码的情况下调整业务过程及处理方式,比如去掉插入审批意见到数据库、取消动作后发送邮件通知等。业务过程的可配置性大大提高。

在工作流管理系统参考模型中,工作流引擎调用业务逻辑就是指的Interface 3,即如下图所示


在示例中,由引擎调用业务处理是通过Function的回调实现的,这个Function需要实现com.opensymphony.workflow.FunctionProvider,然后实现其中的execute(Map transientVars, Map args, PropertySet ps)方法。参数说明:

Map transientVars表示临时变量,这些变量可以通过doAction(long id, int actionId, Map inputs)的inputs传入,也可以通过initialize(String workflowName, int initialAction, Map inputs)的inputs传入,此外还包含一些全局变量,如entry、context、actionId等;

Map args表示调用Function的属性,这些属性在过程定义文件xml中设定;

PropertySet ps 持久变量,这些变量设置后将存储到数据库或其他存储介质,在本示例中通过在doAction中设置该变量,然后在流程跳转时根据该变量进行相应跳转,即实现业务流程的不同流向。

示例代码
在部门主管审批时调用的ApproveFunction,这个Function只是将审批结果插入数据库中
Java代码 复制代码 收藏代码
  1. public void execute(Map transientVars, Map args, PropertySet ps) {   
  2.   logger.info("execute ......");   
  3.   WorkflowEntry entry = (WorkflowEntry) transientVars.get("entry");   
  4.   long wfid = entry.getId();   
  5.   int actionId = ((Integer) transientVars.get("actionId")).intValue();   
  6.   logger.info("execute actionId=" + actionId);   
  7.   int applyID = ((Integer) transientVars.get("applyID")).intValue();   
  8.   String approver = (String) transientVars.get("approver");   
  9.   int opinion = ((Integer) transientVars.get("opinion")).intValue();   
  10.   LeaveApprove LeaveApprove = new LeaveApprove(applyID, approver, opinion);   
  11.   LeaveDAO leaveDao = new LeaveDAO();   
  12.   leaveDao.addLeaveApprove(LeaveApprove);   
  13.   ps.setInt("opinion", opinion);   
  14.   logger.info("execute leaveDao has added leaveApprove!");   
  15. }  


过程定义配置文件中相关的回调
Java代码 复制代码 收藏代码
  1. <step id="2" name="请假申请审核">   
  2.     <actions>   
  3.         <action id="2" name="部门主管审批请假申请">   
  4.             <restrict-to>   
  5.                 <conditions type="AND">   
  6.                     <condition type="beanshell">   
  7.                         <arg name="script">true</arg>   
  8.                     </condition>   
  9.                     <condition type="class">   
  10.                         <arg name="class.name">com.opensymphony.workflow.util.StatusCondition</arg>   
  11.                         <arg name="status">Underway</arg>   
  12.                     </condition>   
  13.                     <condition type="class">   
  14.                         <arg name="class.name">com.opensymphony.workflow.util.OSUserGroupCondition</arg>   
  15.                         <arg name="group">manager</arg>   
  16.                     </condition>   
  17.                 </conditions>   
  18.             </restrict-to>   
  19.             <pre-functions>   
  20.                 [color=red]<function type="class">   
  21.                     <arg name="class.name">com.qiny.leave.ApproveFunction</arg>   
  22.                 </function>[/color]   
  23.                 <function type="beanshell">   
  24.                     <arg name="script">   
  25.                               System.out.println("步骤 2 请假申请审核 pre-functions $$$$$$$");   
  26.                           </arg>   
  27.                 </function>   
  28.             </pre-functions>   
  29.             <results>   
  30.                 <result old-status="Finished" status="Underway" step="5">   
  31.                     <conditions type="AND">   
  32.                         <condition type="beanshell">   
  33.                             <arg name="script">   
  34.                             propertySet.getInt("opinion")==2  
  35.                             </arg>   
  36.                         </condition>   
  37.                     </conditions>   
  38.                     <post-functions>   
  39.                         <function type="beanshell">   
  40.                             <arg name="script">   
  41.                                       System.out.println("步骤 2 请假申请审核 部门经理审批没有通过 ...");   
  42.                                   </arg>   
  43.                         </function>   
  44.                     </post-functions>   
  45.                 </result>   
  46.                 <unconditional-result old-status="Finished" status="Underway" step="3" owner="hr1"/>   
  47.             </results>   
  48.             <post-functions>   
  49.                 <function type="beanshell">   
  50.                     <arg name="script">   
  51.                               System.out.println("步骤 2 请假申请审核 post-functions .......");   
  52.                           </arg>   
  53.                 </function>   
  54.             </post-functions>   
  55.         </action>   
  56.     </actions>   
  57. </step>  


返回顶楼
         回帖地址
00 请登录后投票
 
  • qinysong
  • 等级: 四星会员
  • 性别:
  • 文章: 136
  • 积分: 479
  • 来自: 北京
   发表时间:2007-07-13  
业务过程根据业务数据而变化

在上面的示例中,只有在员工请假申请的天数大于3天时,才需要部门主管审批,若不大于3天则直接由人力资源主管审批,这样业务过程就由业务数据决定,不同的数据有不同的过程。

这个实现是通过action的条件结果完成的,配置如下
Java代码 复制代码 收藏代码
  1. <results>   
  2.   <result old-status="Finished" status="Underway" step="2" owner="manager1">   
  3.     <conditions type="AND">   
  4.       <condition type="beanshell">   
  5.         <arg name="script">   
  6.         propertySet.getInt("dayCount")>3  
  7.         </arg>   
  8.       </condition>   
  9.     </conditions>   
  10.     <post-functions>   
  11.       <function type="beanshell">   
  12.         <arg name="script">   
  13.           System.out.println("步骤 1 提交需求申请 满足条件结果 需部门经理审批...");   
  14.         </arg>   
  15.       </function>   
  16.     </post-functions>   
  17.   </result>   
  18.   <unconditional-result old-status="Finished" status="Underway" step="3" owner="hr1"/>   
  19. </results>  


这里当条件propertySet.getInt("dayCount")>3满足时,导向结果<result old-status="Finished" status="Underway" step="2" owner="manager1">,由部门主管审批
如果条件不满足,则导向默认结果unconditional-result ,由人力资源直接审批

这里的值(propertySet.getInt("dayCount"))从哪里来的呢?是从定义的pre-functions:com.qiny.leave.ApproveFunction来的,在ApproveFunction中我们将数据插入库后,调用了ps.setInt("dayCount", dayCount);
原创粉丝点击