JBPM 3.1.4的J2EE应用整合初探

因为项目需要,准备引入JBPM 3.1.4,因为我们的项目是基于 Spring 2 + Hibernate 3 + Struts2 的,而Spring Modules整合JBPM 是 3.1.4 版的,所以用了JBPM 3.1.4

高版本的设计器还不兼容 MyEclipse ,所以采用JBPM 3.1.4还是比较明智的

 

参考网上的资料初步摸清了整合的方式,这里我想说的是,如何降低引入JBPM框架对我们自有应用的影响。

网上资料及JBPM手册里,好像更多的说明了JBPM自身的特性和一些使用规则。

其实就我现在摸索的情况看来,可以采用流程内置脚本的方式实现所有的JBPM Action Bean的效果,某些特定的业务操作,可以通过”先标记、后处理“的方式在业务服务类中编写,这样的好处是:

1、控制点比较单一

2、对原有的业务逻辑侵入性较小

3、可以基于JBPM控制,通过设值操作,模拟流程的进行(因为没有Action Bean的依赖)

缺点是:

1、内置脚本的执行效率可能较低,如果要求高性能,就应该慎用

2、目前只实现了用来完成审批、审核流程下的非侵入代码测试,还没能在更多的工作流情况下加以验证。

3、为了方面查询和联动,我们修改了TaskInstance(或者利用Description字段),存放一些检索关键字和业务主键,这种做法可能不是很规范

 

简单说来,jbpm例程里的考虑和设计是从 "JBPM为中心”这一出发点考虑,本文中设计及实现是从“业务为中心”这一出发点考虑的。不说了,下面放一些例子代码出来吧。

流程文件,这个流程文件实现了 审核、审批流程,审核、审批流程都是可以通过参数做到可选的效果:

其中,比较特殊的用法

1)通过TrSource变量,了解上一部流程节点的名字,这样可以更好的处理,忽略审核或忽略审批时文档的流向问题

2)通过SetDescription(Docid),将业务单据ID保存到TaskInstance中(实际的项目里,我们在TaskInstance表上加了十个字段)

3)通过skipex="true" 和 skipapp="true" 变量设置,使文档省略审核或省略审批

4)这个流程可以直接挂载到JBPM控制台中执行,不依赖于任何的类

 

<?xml version="1.0" encoding="UTF-8"?>

<process-definition xmlns="" name="docflow">


    <start-state name="create_document">
        <task name="create_document">       
        <controller>
                <variable name="docid" access="read,write,required"
                    mapped-name="docid">
                </variable>               
        </controller>                   
        </task>
        <transition name="create_ok" to="create_juge">
        <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"1create_ok");                   
         </expression>       
        </script>
        </transition>
    </start-state>
    <task-node name="update_document">
        <task name="update_document" description="测试">
            <controller>
                <variable name="docid" access="read"
                    mapped-name="docid">
                </variable>
                <variable name="addinfo" access="read,write,required"
                    mapped-name="addinfo">
                </variable>
            </controller>
            <assignment actor-id="createby" />
        </task>
        <event type="task-create">           
                <script>
                <variable name="docid" access="read"/>
                    <expression>                       
                        taskInstance.setDescription(docid);                               
                    </expression>
                </script>
        </event>
      <transition name="update_ok" to="create_juge">
      <script>
      <variable name="trsource" access="write"/>
      <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"18update_ok");
            </expression>
            </script>     
      </transition>       
    </task-node>


    <task-node name="examine_document">
        <task name="examine_document">
            <controller>
                <variable name="docid" access="read"
                    mapped-name="docid">
                </variable>
                <variable name="examinememo"
                    access="read,write,required" mapped-name="examinememo">
                </variable>
                <variable name="ereply" access="read,write,required"
                    mapped-name="ereply">
                </variable>
            </controller>
            <assignment actor-id="examineby" />
        </task>
        <event type="task-create">           
                <script>
                <variable name="docid" access="read"/>
                    <expression>                       
                        taskInstance.setDescription(docid);                               
                    </expression>
                </script>
        </event>
        <transition name="to_juge1" to="examine_juge">
        <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"2to_juge1");
         </expression>       
        </script>       
        </transition>
    </task-node>

    <decision name="examine_juge" >
      <event type="node-enter">
      <variable name="trsource" access="read,write"/>
      <variable name="skipex" access="read"/>
      <variable name="test1" access="read,write"/>
      <variable name="test2" access="read,write"/>
      <script>     
          trsource=executionContext.getTransitionSource().getName();
          //System.out.println(executionContext.getTransition().getName());
          //System.out.println(skipex);
          System.out.println(trsource);
            test1=((trsource.equals("create_juge"))&amp;&amp;(skipapp.equals("false")));
          test2=((trsource.equals("create_juge"))&amp;&amp;(skipapp.equals("true")));
          System.out.println(test1);
          System.out.println(test2);
      </script>        
      </event>  
        <transition name="examine_ok" to="approve_document">
                
        <condition expression='#{((((trsource=="examine_document") &amp;&amp; (ereply=="ok")))        ||        ((trsource=="create_juge") &amp;&amp; (skipex=="true"))) &amp;&amp;(skipapp!="true")}'/>

        <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
                //System.out.println(skipapp);
                System.out.println(trsource+"3examine_ok");
         </expression>       
        </script>   
        </transition>
        <transition name="examine_cancle" to="cancle_document">
        <condition expression='#{((trsource=="examine_document") &amp;&amp; (ereply=="cancle"))}'/>
        <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"4examine_cancle");
         </expression>       
        </script>   
        </transition>
    <transition name="skip_app" to="approve_juge">   
       <condition expression='#{((((trsource=="examine_document") &amp;&amp; (ereply=="ok")))        ||        ((trsource=="create_juge") &amp;&amp; (skipex=="true"))) &amp;&amp;(skipapp=="true")}'/>     
    <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            //System.out.println(skipapp);
            System.out.println(trsource+"5skip_app");
         </expression>       
        </script>   
    </transition>
    <transition name="examine_notok" to="create_juge">
        <condition expression='#{((trsource=="examine_document") &amp;&amp; (ereply=="notok"))||(((trsource=="approve_juge") &amp;&amp; (areply=="notok")) &amp;&amp;( skipex=="true"))}'/>
    <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"6examine_notok");
         </expression>       
        </script>   
    </transition>
     <transition name="examine_back" to="examine_document">
        <condition expression='#{(((trsource=="approve_juge") &amp;&amp; (areply=="notok")) &amp;&amp;( skipex!="true"))}'/>
    <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"6examine_back");
         </expression>       
        </script>     
      </transition>
    </decision>

    <task-node name="approve_document">
        <task name="approve_document">
            <controller>
                <variable name="docid" access="read"
                    mapped-name="docid">
                </variable>
                <variable name="examinememo" access="read"
                    mapped-name="examinememo">
                </variable>
                <variable name="ereply" access="read"
                    mapped-name="ereply">
                </variable>
                <variable name="approvememo"
                    access="read,write,required" mapped-name="approvememo">
                </variable>
                <variable name="areply" access="read,write,required"
                    mapped-name="areply">
                </variable>
            </controller>
            <assignment actor-id="approveby" />
        </task>
        <event type="task-create">           
                <script>
                <variable name="docid" access="read"/>
                    <expression>                       
                        taskInstance.setDescription(docid);
        </expression>
        </script>
        </event>
        <transition name="to_juge2" to="approve_juge">
        <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"7to_juge2");
         </expression>       
        </script>   
        </transition>
    </task-node>

    <decision name="approve_juge" >

        <transition name="approve_notok" to="examine_juge">
       <condition expression='#{((trsource=="approve_document") &amp;&amp; (areply=="notok"))}'/>
        <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"8approve_notok");
         </expression>       
        </script>   
        </transition>
       
        <transition name="approve_ok" to="apply_document">
        <condition expression='#{(((trsource=="approve_document") &amp;&amp; (areply=="ok")) ||((trsource=="examine_juge") &amp;&amp; (skipapp=="true")))}'/>       
        <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"9approve_ok");
         </expression>       
        </script>   
        </transition>
       
        <transition name="approve_cancle" to="cancle_document">
               <condition expression='#{((trsource=="approve_document") &amp;&amp; (areply=="cancle"))}'/>
        <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"10approve_cancle");
         </expression>       
        </script>   
        </transition>
    </decision>

    <node name="apply_document">
            <event type="node-enter">
      <script>     
                executionContext.getContextInstance().setVariable("docstatus", "apply_document");
            </script>
            </event>
    <!--
      <event type="node-enter">
          <action name="applydoc" class="org.springmodules.workflow.jbpm31.JbpmHandlerProxy">
                 <targetBean>applyDoc</targetBean>
            <factoryKey>jbpmConfiguration</factoryKey>
         </action>        
      </event>
               -->
        <transition name="apply_ok" to="end">       
        <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"11apply_ok");
         </expression>       
        </script>   
        </transition>
    </node>

    <node name="cancle_document">
        <event type="node-enter">
      <script>     
                executionContext.getContextInstance().setVariable("docstatus", "cancle_document");
            </script>
            </event>
<!--
         <event type="node-enter">
          <action name="cancledoc" class="org.springmodules.workflow.jbpm31.JbpmHandlerProxy">
                 <targetBean>cancleDoc</targetBean>
            <factoryKey>jbpmConfiguration</factoryKey>
         </action>
      </event>
       -->

        <transition name="cancle_ok" to="end">
        <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"13cancle_ok");
         </expression>       
        </script>   
        </transition>
    </node>


    <end-state name="end"></end-state>
   
   <decision name="create_juge" >
       <event type="node-enter">
      <variable name="trsource" access="read,write"/>
      <variable name="skipex" access="read"/>
      <variable name="test1" access="read,write"/>
      <variable name="test2" access="read,write"/>
      <script>     
          trsource=executionContext.getTransitionSource().getName();
          test1=((trsource.equals("create_document"))&amp;&amp;(skipex.equals("false")));
          test2=((trsource.equals("create_document"))&amp;&amp;(skipex.equals("true")));
          System.out.println(test1);
          System.out.println(test2);
      </script>        
      </event>  
      <transition name="to_examine" to="examine_document">     
      <condition expression='#{((trsource=="create_document")||(trsource=="update_document"))&amp;&amp;(skipex!="true")}'/>
      <script>
            <variable name="trsource" access="write"/>
            <expression>
                trsource=executionContext.getTransitionSource().getName();
                System.out.println(trsource+"15to_examine");
             </expression>       
            </script>   
      </transition>
      <transition name="skip_ex" to="examine_juge" >
            <condition expression='#{((trsource=="create_document")||(trsource=="update_document"))&amp;&amp;(skipex=="true")}'/>
            <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"16skip_ex");
         </expression>       
        </script>   
      </transition> 
      <transition name="to_update" to="update_document">
      <condition expression='#{(trsource=="examine_juge")}'/>
      <script>
        <variable name="trsource" access="write"/>
        <expression>
            trsource=executionContext.getTransitionSource().getName();
            System.out.println(trsource+"17to_update");
         </expression>       
        </script>         
      </transition>
   </decision>

</process-definition>

 

 

下面再贴一个测试类的代码 和 一个JBPM公用服务类的代码(简单封装)

package com.hust.jbpmtest.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import junit.framework.TestCase;

import org.jbpm.taskmgmt.exe.TaskInstance;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.hust.buss.service.CommonService;
import com.hust.jbpm.service.JbpmService;
import com.hust.jbpmtest.model.JbpmDoc;

public class JbpmDocflowTest extends TestCase {

    private static ApplicationContext ctx;
    private static JbpmService mgr;
    private static JbpmDocService mgr1;
    private static CommonService cmgr;
    private static boolean inited = false;
    private long tid;
    private String docid;
    private JbpmDoc doc;
    private HashMap compuParams;

    public void setUp() throws Exception {
        super.setUp();
        if (!inited) {
            init();
            inited = true;
        }
        // 准备一个业务实体
        doc = new JbpmDoc();
        docid = cmgr.getPks(JbpmDoc.class.toString(), "ABC");
        doc.setDocid(docid);
        doc.setTitle("标题内容");
        // 计算参量
        compuParams = new HashMap();
        compuParams.put("age", Long.valueOf("36"));
        compuParams.put("year", new Long("5"));
        compuParams.put("base", new Long("300"));
        compuParams.put("obj", doc);
        Object[] obj1 = new Object[] { "a", "b" };
        Object[] obj2 = new Object[] { "c", "d" };
        List plist = new ArrayList();
        plist.add(obj1);
        plist.add(obj2);
        compuParams.put("plist", plist);
    }

    protected void tearDown() throws Exception {
        super.tearDown();
        doc = null;
        docid = "";
        compuParams = null;
    }

    public void init() {
        ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
        mgr = (JbpmService) ctx.getBean("jbpmService");
        mgr1 = (JbpmDocService) ctx.getBean("jbpmDocService");
        cmgr = (CommonService) ctx.getBean("commonService");
    }

   
    public void testDeployProcessDefinition() {
        mgr.removePisByName("docflow");
        mgr.removePdefsByName("docflow");
        assertNull("not deleted all Definition", mgr
                .getPdefByName("docflow"));


 assertNotNull( "Definition should not be null", mgr
.deployProcessDefinitionByFile("com/hust/jbpmtest/workflow/autocompu/processdefinition.xml"));
    }

    public void testAllNormal() throws Exception {

        // 需要注入的流程变量
        HashMap map = new HashMap();
        // 配置参量
        map.put("pkname", "docid");
        map.put("skipex", "false");
        map.put("skipapp", "false");
        // 业务主键参量
        map.put("docid", docid);
        map.put("compuparams", compuParams);
        // 启动一个正常流程,并设置发起者和注入流程变量
        TaskInstance taskInstance = mgr.executeNewTi("docflow", "createby",
                null, map);
        mgr.saveObject(doc);
        // 下一步审核流程任务号
        tid = mgr.getTidByBuss("examine_document", docid);
        // 正常数据流程 数据
        HashMap tiparams = new HashMap();
        tiparams.put("ereply", "ok");
        tiparams.put("examinememo", "同意");
        // 继续下一步正常流程
        mgr.executeTi(tid, null, tiparams, null, null);
        // 下一步审批流程任务号
        tid = mgr.getTidByBuss("approve_document" ,docid);
        // 正常数据流程 数据
        HashMap tiparams1 = new HashMap();
        tiparams1.put("areply", "ok");
        tiparams1.put("approvememo", "同意");
        // 继续正常的审批流程
        mgr.executeTi(tid, null, tiparams1, null, null);

}

}

 

 

JBPM服务类的代码

 

 

 

 

package com.hust.jbpmtest.service;

import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.jbpm.taskmgmt.exe.TaskInstance;

import com.hust.buss.service.CommonService;
import com.hust.buss.util.Constants;
import com.hust.core.model.PageObject;
import com.hust.core.service.BaseServiceImpl;
import com.hust.core.service.CallBack;
import com.hust.core.util.TextUtil;
import com.hust.jbpm.service.JbpmService;
import com.hust.jbpmtest.model.JbpmDoc;

public class JbpmDocServiceImpl extends BaseServiceImpl implements
        JbpmDocService {
    JbpmService jbpmService;
    CommonService commonService;

    public void executeTask(String taskname,JbpmDoc jbpmDoc,HashMap tiparams) throws Exception {
        long tid=jbpmService.getTidByBuss(taskname, jbpmDoc.getDocid());
        jbpmService.executeTi(tid, null, tiparams, null, null);       
       
        String docstatus=jbpmService.getTnameByBuss(jbpmDoc.getDocid());
        if (docstatus.equals("")){
            jbpmDoc.setDocstatus((String)jbpmService.getTi(tid).getContextInstance().getVariable("docstatus"));
        }else{
            jbpmDoc.setDocstatus(docstatus);
        }       
        this.updateObject(jbpmDoc);
    }

    public void setJbpmService(JbpmService jbpmService) {
        this.jbpmService = jbpmService;
    }
   
    public void createJbpmDoc(JbpmDoc jbpmDoc,HashMap tiparams){
   
        // 启动一个正常流程,并设置发起者和注入流程变量
        TaskInstance taskInstance = jbpmService.executeNewTi("docflow", "createby",
                null, tiparams);       
        jbpmDoc.setDocstatus(jbpmService.getTnameByBuss(jbpmDoc.getDocid()));
        this.saveObject(jbpmDoc);
    }
    public PageObject getJbpmList(String taskName,int pageno){
        //获得特定环节的业务单据列表 及 附属的TaskInstance列表
        //TaskName为空,表示显示所有的待办
        //TaskName为all
        String hql=" select distinct JbpmDoc  from JbpmDoc JbpmDoc,TaskInstance TaskInstance where JbpmDoc.docid=TaskInstance.description ";
        String countHql=" select count( distinct JbpmDoc) from JbpmDoc JbpmDoc,TaskInstance TaskInstance where JbpmDoc.docid=TaskInstance.description  ";
        String todo=" and       TaskInstance.isSuspended != true  and TaskInstance.isOpen = true  ";
        String all=" and  TaskInstance.name in('create_document','update_document','examine_document','approve_document')";
       
        if (taskName.equals("all")){
            //不附加条件
            hql=hql+all;
            countHql=countHql+all;
        } else if (taskName.equals("todo")){
            //附加待办条件
            hql=hql+todo;
            countHql=countHql+todo;           
           
        } else{
            hql=hql+todo+" and  TaskInstance.name="+TextUtil.toSQL(taskName, TextUtil.Text_TYPE);
            countHql=countHql+todo+" and TaskInstance.name="+TextUtil.toSQL(taskName, TextUtil.Text_TYPE);
        }
        PageObject list=getPageList(countHql, hql, Constants.MAX_QUERYRESULT_PER_PAGE, pageno);       
        return list;
    }

    public List getTaskInstances(String busscode) {
        String hql=" select TaskInstance  from TaskInstance TaskInstance where TaskInstance.description=:busscode "
        + " and  TaskInstance.name in('create_document','update_document','examine_document','approve_document') order by TaskInstance.create ";       
        List list=this.findByNamedParam(hql, "busscode", busscode);
        commonService.transData(list, null,new  CallBack(){
            public void execute(Object obj, HashMap map) throws Exception {
                TaskInstance ti=(TaskInstance)obj;
                String html="";
                Map tivars=ti.getVariables();
                if (ti.getName().equals("create_document")){
                    html=tivars.get("actionuser")+"建立文档";
                }else if (ti.getName().equals("update_document")){
                    html=tivars.get("actionuser")+"修订文档,附加说明:"+tivars.get("addinfo");
                }else if (ti.getName().equals("examine_document")){
                    html=tivars.get("actionuser")+"审核文档,审核意见:"+tivars.get("ereply")+",审核说明:"+tivars.get("examinememo");               
                }else if (ti.getName().equals("approve_document")){
                    html=tivars.get("actionuser")+"审批文档,审核意见:"+tivars.get("areply")+",审批说明:"+tivars.get("approvememo");
                   
                }
                ti.setDescription(html);
            }
           
        });
       
       
        return list;
    }

    public void setCommonService(CommonService commonService) {
        this.commonService = commonService;
    }


}

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值