工作流引擎调用业务逻辑

在基于工作流进行业务系统开发时,通常需要在某些事件发生时或某些情况下,由低层工作流引擎调用上层的业务处理逻辑,比如在示例业务需求中,当部门主管审批员工请假申请时,审批事件发生时需要将审批意见插入到数据库表中,并进入后续相应的步骤,这里的将审批意见插入数据库,可以在业务程序中审批处理代码中直接插入,也可以只让审批处理代码只负责调用工作流引擎的“审批处理”步骤的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. }  
  public void execute(Map transientVars, Map args, PropertySet ps) {
    logger.info("execute ......");
    WorkflowEntry entry = (WorkflowEntry) transientVars.get("entry");
    long wfid = entry.getId();
    int actionId = ((Integer) transientVars.get("actionId")).intValue();
    logger.info("execute actionId=" + actionId);
    int applyID = ((Integer) transientVars.get("applyID")).intValue();
    String approver = (String) transientVars.get("approver");
    int opinion = ((Integer) transientVars.get("opinion")).intValue();
    LeaveApprove LeaveApprove = new LeaveApprove(applyID, approver, opinion);
    LeaveDAO leaveDao = new LeaveDAO();
    leaveDao.addLeaveApprove(LeaveApprove);
    ps.setInt("opinion", opinion);
    logger.info("execute leaveDao has added leaveApprove!");
  }


过程定义配置文件中相关的回调
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>  
		<step id="2" name="请假申请审核">
			<actions>
				<action id="2" name="部门主管审批请假申请">
					<restrict-to>
						<conditions type="AND">
							<condition type="beanshell">
								<arg name="script">true</arg>
							</condition>
							<condition type="class">
								<arg name="class.name">com.opensymphony.workflow.util.StatusCondition</arg>
								<arg name="status">Underway</arg>
							</condition>
							<condition type="class">
								<arg name="class.name">com.opensymphony.workflow.util.OSUserGroupCondition</arg>
								<arg name="group">manager</arg>
							</condition>
						</conditions>
					</restrict-to>
					<pre-functions>
						[color=red]<function type="class">
							<arg name="class.name">com.qiny.leave.ApproveFunction</arg>
						</function>[/color]
						<function type="beanshell">
							<arg name="script">
                                System.out.println("步骤 2 请假申请审核 pre-functions $$$$$$$");
                            </arg>
						</function>
					</pre-functions>
					<results>
						<result old-status="Finished" status="Underway" step="5">
							<conditions type="AND">
								<condition type="beanshell">
									<arg name="script">
									propertySet.getInt("opinion")==2
									</arg>
								</condition>
							</conditions>
							<post-functions>
								<function type="beanshell">
									<arg name="script">
                                        System.out.println("步骤 2 请假申请审核 部门经理审批没有通过 ...");
                                    </arg>
								</function>
							</post-functions>
						</result>
						<unconditional-result old-status="Finished" status="Underway" step="3" owner="hr1"/>
					</results>
					<post-functions>
						<function type="beanshell">
							<arg name="script">
                                System.out.println("步骤 2 请假申请审核 post-functions .......");
                            </arg>
						</function>
					</post-functions>
				</action>
			</actions>
		</step>


0 请登录后投票
 
   发表时间: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>  
<results>
  <result old-status="Finished" status="Underway" step="2" owner="manager1">
    <conditions type="AND">
      <condition type="beanshell">
        <arg name="script">
        propertySet.getInt("dayCount")>3
        </arg>
      </condition>
    </conditions>
    <post-functions>
      <function type="beanshell">
        <arg name="script">
          System.out.println("步骤 1 提交需求申请 满足条件结果 需部门经理审批...");
        </arg>
      </function>
    </post-functions>
  </result>
  <unconditional-result old-status="Finished" status="Underway" step="3" owner="hr1"/>
</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);
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值