转:传智播客—jbpm与OA项目(二)

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

 

一、昨日回顾

 

转:传智播客—jbpm与OA项目(二)

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接口。如:

 

转:传智播客—jbpm与OA项目(二)

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看作是一个大节点。内部包含多条并行的子节点流程。

      

转:传智播客—jbpm与OA项目(二)

Start-state

fork

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

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

End-state

 

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

 

2.自定义节点

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

                    Node + action示例:

转:传智播客—jbpm与OA项目(二)

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个事件的执行顺序:

转:传智播客—jbpm与OA项目(二)

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" />

            <span style="font-family: 'Courier New'; color: teal; font-size: 9pt;" lang="EN-