posts - 78, comments - 34, trackbacks - 0, articles - 1
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

今日继续讲解jbpm框架,早上汤老师领着大家把昨天的内容复习了一下,然后做了总结。总结之后十分清晰。

 

一、昨日回顾

 

clip_image001

1.          部署流程定义:“deployProcessDefinition”向“jbpm_processdefinition 表中添加新的流程定义记录,同时向其子表添加详细信息。

2.          创建流程实例:“findLatestProcessDefinition”到“jbpm_processdefinition”表中获取指定名称的流程定义。“createProcessInstance”创建的流程实例被保存到“jbpm_ processinstance”表中。“pi.getRootToken().signal()”中的Token指向当前任务(游标),signal发出一个信号到达下一个任务节点,同时向“jbpm_ taskinstance 表中添加一个任务节点。“pi.getRootToken().signal()”为到达第一个任务节点。

3.          获取任务实例列表:“getTaskList”根据指定的actorId到“jbpm_ taskinstance”表中获取对应的任务列表。

4.          开始任务:“getTaskInstance”到“jbpm_ taskinstance”表中获取指定的任务实例。“start”向“jbpm_ taskinstance”表中对应的记录添加任务起始时间。

5.          结束任务:“getTaskInstance”到“jbpm_ taskinstance”表中获取指定的任务实例。“end”向“jbpm_ taskinstance”表中对应的记录添加任务结束时间。“end”内部调用“taskIns.getToken().signal();”指向下一个任务节点。

 

今日新内容主要为四点,流程定义文档、节点、动作与事件、任务分配。突然的感觉到事件在JavaEE中被广泛应用,看来事件驱动还是十分重要的。

 

二、流程定义文档(PAR

       1.打包流程文档时必须使用zip格式。

    

         2.在根目录中或zip压缩文件中,包含如下文件:

i.           processdefinition.xml(必须,jbpm的流程配置文件。)

ii.          processimage.jpg(可选,流程设计器生成的图片文件。)

iii.        gpd.xml(可选,流程设计器中图元的坐标等信息。)

iv.        classes/(可选,存放用到的java类。)

 

3.eclipsejbpm插件可以打包和部署流程,在设计页面的标签的旁边“Deployment”页面。在“Files and Floders”与“Java Classes and Resources”中,选择将要打包或部署的文件。“Local Save Settings”打包到。“Deployment Server Settings”发布到JBOSS WEB容器,此时必须走动JBOSS WEB容器,采取默认设置即可。

 

4.更新的问题(版本)

我们每次部署流程时,JBOSSWEB容器都会为流程设置一个新的版本,而不会去覆盖之前部署的应用。使用之前的应用与对应的版本保留,不会造成数据出错。所以每次应该重新部署应用,也不要删除以前的应用。

如果被删除或覆盖,新部署的流程相比以前的流程。多了或少了几个任务节点,那使用之前的数据访问就会出错。

 

三、节点

1.预定义节点

1)    Start-state:开始状态节点。

2)         End-state:结束状态节点。

3)         Task-Node:任务节点,非常重要,昨天已经学习过。

4)         Decision:决策分支节点,此节点的handler委托类(delegation)必须实现DecisionHandler接口。如:

 

clip_image002

Start-state

需要为Decisionhandler页面的delegation属性添加一个实现“DecisionHandler”接口的类。

此类返回一个String类型,用于指定decision节点执行哪个分支。

实现“DecisionHandler”接口的类:

package cn.itcast.cc.jbpm.node.decision;

 

import org.jbpm.graph.exe.ExecutionContext;

import org.jbpm.graph.node.Decision;

import org.jbpm.graph.node.DecisionHandler;

 

public class DecisionNodeTest extends Decision implements DecisionHandler {

    private static final long serialVersionUID = 1L;

    @Override

    public String decide(ExecutionContext arg0) throws Exception {

        //ExecutionContext节点的执行环境,通过这个参数可以获取所有信息。

        return "t2";//执行transition名为“t2”的分支。

    }

}

 

5)         Fork/join:分叉与合并结点,可以把Fork/join看作是一个大节点。内部包含多条并行的子节点流程。

      

clip_image004

Start-state

fork

两个分支是并行关系。直接两个分支全部执行完成,才会到达join。此处自动生成transition名称,tqt3。如果没有,重新连接即可。必须具有transition名称。

Join,选择到此处时不全停留,直接到达end-state

End-state

 

6)         State:状态节点,当流程执行到此节点时会暂停,直到调用tokensignal方法时才会继续向下执行。(没有别的用处)

 

2.自定义节点

                    自定义节点的实现需要使用普通“Node”节点,与节点Action动作相配合。以实现预定义节点所不能完成的功能。

                    Node + action示例:

clip_image005

Start-state

Node

End-state

                    node1action->details属性页面的Handler添加一个实现了“ActionHandler”接口的类(必须选中页面中的“Configuration Action”),我为在此类中打印一条语语句:

                   

package cn.itcast.cc.jbpm.node.customize;

 

import org.jbpm.graph.def.ActionHandler;

import org.jbpm.graph.exe.ExecutionContext;

 

public class CustomizeAction implements ActionHandler {

    private static final long serialVersionUID = 1L;

    @Override

    public void execute(ExecutionContext executionContext) throws Exception {

        //ExecutionContext节点的执行环境,通过这个参数可以获取所有信息。

        System.out.println("*****CustomizeAction*****");

    }

}

 

四、动作与事件

动作我们在第三部分末尾已经介绍过,Jbpm的的节点包含三类事件(共7个事件)。Jbpm7个事件的执行顺序:

clip_image006

node-leave:离开start-state1节点,可通过插件配置。

Transition:从start-sate1过渡到task-node1的事件,可通过插件配置。

node-enter:进入task-node1节点,可通过插件配置。

task-create:创建任务事件,需要插件/手动配置。

task-assign:分配任务事件,需要插件/手动配置。

task-start:任务开始事件,需要插件/手动配置。

task-end:任务结束事件,需要插件/手动配置。

上表中的事件是jbpm流程中比较常用的事件,事件不影响流程的执行。

 

         让我们为上面的流程添加7个,表中对应的事件。事件处理统一使用一个实现了“ActionHandler”接口的类:

package cn.itcast.cc.jbpm.node.event;

 

import org.jbpm.graph.def.ActionHandler;

import org.jbpm.graph.exe.ExecutionContext;

 

public class NodeEventTest implements ActionHandler {

    private static final long serialVersionUID = 1L;

 

    @Override

    public void execute(ExecutionContext executionContext) throws Exception {

        // 打印事件类型

        System.out.println(executionContext.getEvent().getEventType());

    }

}

 

         processdefinition.xml文件内容为:

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

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

   

    <start-state name="start-state1">

        <transition to="task-node1"></transition>

        <event type="node-leave">

            <action class="cn.itcast.cc.jbpm.node.event.NodeEventTest"

                name="printNodeEventType"></action>

        </event>

    </start-state>

   

    <task-node name="task-node1">

   

        <task name="下订单">

            <assignment actor-id="客户"></assignment>

           

            <event type="task-create">

                <action ref-name="printNodeEventType" />

            </event>

            <event type="task-assign">

                <action ref-name="printNodeEventType" />

            </event>

            <event type="task-start">

                <action ref-name="printNodeEventType" />

            </event>

            <event type="task-end">

                <action ref-name="printNodeEventType" />

            </event>   

        </task>

       

        <event type="node-enter">

            <action ref-name="printNodeEventType"></action>

        </event>

       

        <transition to="end-state1"></transition>

    </task-node>

    <end-state name="end-state1">

        <event type=""></event>

    </end-state>

</process-definition>

        

如果 task-node中包含多个task。将event放在task外部,task-node的内部,所有的task将共用同一个事件处理类。如果将event放在task内部,task将使用各自内部的事件处理类。

 

         将流程发布到JBOSSWEB容器中(注意将类“NodeEventTest”一同发布),一步步执行查看控制台的输出。

 

五、任务分配

1.个人任务(推模型)

        个人任务属于个人,只有个人能看到,必须由个人完成。个人任务的分配方式:

1)         手动添加,通过设计器设置taskActor属性值。

2)         Actor:通过设计器使用表达式将Actor设置为#{customer},在事件处理函数中通过“executionContext.getContextInstance().setTransientVariable(name, value)”设置变量值,动态更改actor

3)         Task的“Assignment->Handler”添加一个实现了AssignmentHandler接口的类,在“assign”方法中调用“assignable.setActorId(actor);”方法设置Actor属性值。

4)         可以在程序的任何位置使用“TaskInstance.setActorId(actor)”设置Actor的值。

 

2.组任务(拉/竞争模型)

组任务属于小组,只有小组成员可以查看,但必须仅有一个人来完成。组任务的分配试:

1)         手动添加,通过设计器设置taskPooledActors属性值,使用“,”分隔。

2)         PooledActors:通过设计器使用表达式将PooledActors属性设置为#{actors},在事件处理函数中通过“executionContext.getContextInstance().setTransientVariable(name, value)”设置变量值,动态更改actor

3)         Task的“Assignment->Handler”添加一个实现了AssignmentHandler接口的类,在“assign”方法中调用“assignable. setPooleActors (actors);”方法设置PooleActors属性值。

4)         可以在程序的任何位置使用“taskInstance.setPooledActors(actors)”,设置PooledActors的值。

 

3.查询

1)         个人任务:jbpmContext.getTaskMgmtSession().findTaskInstances (actorId)

2)         组任务:jbpmContext.getTaskMgmtSession().findPooledTaskInstances(actorId)

actorId可以屏蔽pooledActors

4.Swimlane(泳道)

                   汤兄弟今天只是简单介绍了一下泳道,这个功能并不常用。

         泳道图:

clip_image008

 

         OK,今天的内容到此结束。明天就开始我们的OA系统了,主要使用struts+hibernate+jbpm开发!

 

         哈哈,加油!


只有注册用户登录后才能发表评论。


网站导航: