首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 软件管理 > 软件架构设计 >

转:传智播客-Jbpm(2)

2012-10-07 
转:传智播客--Jbpm(二)1. 结点类型:-- start-state:开始节点;-- end-state:结束结点;-- task-node:任务结

转:传智播客--Jbpm(二)
1. 结点类型:
    -- start-state:开始节点;
    -- end-state:结束结点;
    -- task-node:任务结点
        -- 创建任务实例;
        -- 处于等待状态;
        -- 有多个任务时,什么时候离开结点?所有任务都执行完,课堂测试使用了2个任务,不分先后顺序;
        -- transitionName的作用:进入下一个结点;
        -- 一个任务都没有的任务结点的行为;
        -- 我的问题:当一个任务结点中有多个任务实例时,它们的执行顺序是怎么定义?

        == 举例:
            -- 原有的图中,去掉变量定义;将填写报销单,分为2个任务;
                1,填写报销单;2,扫描发票;
            -- 空指针异常:审批的transitionName只指定了一个"to end",由于需要对transitionName进行排序;
            -- 有多个结点时,需要指定transitionName;
            -- 离开结点时使用signal才有效;
                如有2个任务,必须都完成才能离开结点;否则执行signal无效;
          
    -- state-node: 状态结点
        -- 等待结点;
        -- 3个结点演示;
        -- 每signal一次才进入下一个结点;
        -- 使用:经理审批完毕,发送邮件给员工,告诉报销结果;
            一个专门的邮件发送程序;
            邮件可能很久以后才能发送;
            邮件发送后流程实例结束;
        -- 不能放任务;

     -- decision :决策结点
        -- 报销额超过500元,需要总经理审批;
        -- 多一个分支;
        -- 精简了,去掉领款结点;
        -- 经理审批有2种走向:
            -- 结束;
            -- 总经理审批;
            ** 这种情况,使用Decision;
        -- 增加一个Decision结点;
            -- 经理审批后进入Decision结点;
            -- Decision结点决定流向;
            -- 问题:Decision如何知道业务?
                -- 使用Java代码,实现接口的某个方法;
                -- Handler: DecisionHander
                    -- decide()方法:返回值是什么?TransitionName;
                        (money > 500 ) to 总经理;
                        (money <= 500 ) to end;
                    -- decide()的参数ExecutionContext ec;
                        获取先前定义好的变量;
                            ec.getContextInstance().getVariable("");
                        这里不能设置变量;
                    -- "当前"的含义?
                        当流程执行到这个结点时,当前环境信息。
                -- 配置Handler的className(全类名,反射或其他方式)
                -- Decision结点增加一个handler子元素;
                -- Decision结点通过判断使用其中的一个结点离开;
        *** 写Demo测试Decision结点的使用方法;
            -- 在原有的基础上修改;
            -- 逐步测试:
                -- 测试 money=300
                    -- 正常;
                -- 测试 money=800
                    -- 不增加任务:出错;
                    -- 增加总经理审批: 正常;

        -- Decision知道业务的第二种方式:使用expression_r(表达式);
            -- 选择表达式方式;
            -- 返回的也是字符串,代表TransitionName;
            -- 这里的表达式的写法:同EL表达式,"#"
                #{money gt 500 ?  ("to 总经理审批"): ("to end")}
            -- decision增加属性expression;

        -- Decision知道业务的第三种方式:只有Decision的transition才可以有起作用的表达式;******
            -- 什么时候为true,什么时候使用这个transition离开结点;
            -- 代码不变既可测试;
            -- 避免这2种情况:
                -- 多个计算值都为真,取第一个为真;
                -- 所有的计算都为假,取第一个为真;
            -- 3种方法同时写,调用的顺序:
                -- 1, Decision class;
                -- 2, Decision expression;
                -- 3, transition expression;
   
        -- expression:表达式;
            -- 与EL相似;
            -- 有可以直接使用的对象;
            -- 可以使用变量;

    -- fork / join: 分支和合并;
        -- 目前的节点只有一条流程走;
        -- 买家打款,商家发货2个结点同时走的情况;
      
        -- 父子令牌;
            运行时可用看见3个令牌的显示背景颜色;
        -- 3个Token停留的情况;
            rootToken不停留在join结点,直接进入join的下一个结点;

        -- 实现拍卖的流程;
            fork结点分开流程;
            join结点合并流程
          
    -- node:自定义结点;
        -- 定制:实现ActionHandler接口;
        -- 以报销为例:经理审批后给申请人发一条消息:模拟在控制台打印一条语句;
        -- 例子以state代替,不使用TaskNode;
        -- Node:
            -- Action属性的配置;
                -- Expression;
                -- Handler: 实现ActionHander.execute(ec);
                    syso: "审批完毕!";
                    ec.getToken().signal(); 显示地发信号
                -- NullPointerException;
            -- 将类字节码部署进去;
                在部署时选中包;
            -- 没有action属性的node结点,直接离开,不用signal;
                测试:配置2个node,一个有action,一个没有,比较两者的区别;
              
        -- Action:一段代码
            -- 属性:
                -- class: Java类;
                -- name: 其他的node使用这个Action,使用name值;
                -- ref-name:使用名字引用其他的action;
          
            -- Action:
                node / event;
           
        -- 同样是操作:两种实现方案:
            -- Action;
            -- script;

        -- script 和 beanshell;
            -- 与Java相似,可以使用Java类;
            -- 上面的Action使用script:
                syso:"经理审核完毕";

            -- CDATA
                脚本;
            -- 如何实现脚本的重用,引用?
                -- 脚本的地方:script增加name属性;
                -- 重用的地方:action name
                -- 脚本也可以使用已有的变量;
            -- 能使用Action的地方都能使用Script;


        **************** XML提示 *******************
        1. 加入约束文件; 18.4
        2. xmlns=""指定命名空间;
      
      
    -- 事件:
        -- 什么情况下有事件?
            如进入/离开结点;使用Transition等

        -- 测试事件
            定义一个Script,在某个事件触发的时候执行;
            Events->New Event
            node-enter->New Action / New Script(使用这个)
                写脚本的内容;
         
        -- 什么地方可以配置事件:
            -- node;
            -- task;
            -- Transition;


任务和变量
----------------------------------------------

2. task: 任务

    -- demo7
        -- 提交申请:填写表单; 扫描发票;
        -- 经理审批:审批;

来源:(http://blog.sina.com.cn/s/blog_5ecfe46a0100dni8.html) - 传智播客--Jbpm(二)_hhl_bj_新浪博客
        -- 默认:2个任务都完成才进入下一个任务结点;
        -- 修改XML:
            task-node属性:signal="last"
            通过修改signal将Token传至下一个任务结点;
            而不管之前的任务是否完成;
          
            signal="last-wait" / first-wait的理解:
            默认进入结点即创建任务,task-create="true";
            如果修改为false,则last-wait等待最后一个任务完成;
            wait表示等待任务创建的含义;

            什么时候不创建任务?通过程序来创建。

        ** 流程实例的完成和任务实例的完成之间的关系;
          
        -- 动态创建不确定数量的任务实例;
            经理审批:TaskNode
            (1) task-create="false";
            (2) action:
                ActionHandler;

                根据经理的数量,创建相应数量的任务实例,并分配给相应的参与者(经理)

            (3) 写这个ActionHandler
                TaskMgmtInstance.createTaskInstance();
            (4) jbpm中测试!


3. 变量:
    -- 变量的访问和赋值与Token有关;
    -- set变量后,它被保存在数据表中;
    -- 实体:BizForm 业务表单
        id, name;
        要将BizForm的对象存入数据库:
            -- 1. 实现序列化接口;
            -- 2. 不实现序列化接口,使用Hibernate管理;

  
        contextInstance().setVariable("bizForm", bizForm);
        -》
        jbpmContext.getSession().save(bizForm);
        contextInstance().setVariable("bizFormId", bizFormId);
      
        如何确定获取的类型;
        pi.getContextInstance().setVariable();
        pi.getContextInstance().getVariable();
      
        保存的是类名和id;
        要求主键必须是long型的;long id;

   --   临时变量;2009-5-12 
        set/getTransientVariable();

   张孝祥讲解:
        1. 定义流程:XML;
        2. 部署流程;
        3. 操作菜单;
            启动流程;
            获取任务;
            最后一个人获取任务且办理后,流程结束;



练习:
    请假流程:提交申请,

    pooled-actors=" , "

    个人任务:
    组任务; jbpmContext.getGroupTaskList(actorIds);
             jbpmContext.getTaskMgmtSession().findPooledTaskInstances(actorId / actorIds);

    拾取任务:ti.setActorId(actorId);
        拾取任务过去,组任务就没有了,成了个人任务了;

    退回任务到组任务列表:一般管理员来处理
        ti.setActorId(null);

热点排行