jBPM二(表达业务流程)

业务流程包括三部分:

  1. 活动 Activity / 节点 Node (有很多种,不同的类型有不同的功能,必须要有一个Start Activity)
  2. 连线 Transition / 转移 (从一个Activity指向另一个Activity)
  3. 事件 Event 

Transition

开始活动中有且只能有一个连线,并且一个流程实例启动后,会在开始活动之后的一个活动处停下,所以只能有一个开始活动和连线.结束活动不能有连线.其它的活动可以一个或多个连线.当有一个或多个连线的时候,必须使用指定的连线名称离开当前活动,不指定连线名称默认为null,最多只能有一个名称为null的连线名称.相应的语法为:

TaskService.completeTask(taskId, outcome);

指定的连线的名称一定要和流程图上的连线名称相同,包括空格.如果没有找到相应的连线,则会抛出异常.

jBPM4.4中有很多地方都要用到连线名称,其API中也有很多种叫法,比如outcome、signalName、transionName  都是表示Transition的名称.variables、parameters都是表示流程变量的集合Map.

Activity

活动分为两种:预定义活动和自定义活动. 预定义活动就是可以可以直接使用的活动.比如Start,End等.

下面就对几种常见的预定义活动进行说明:

开始活动/Start

表示流程的开始,一个流程图中有且只能有一个Start.而且Start必须要有且只能有一个Transition.不能有其他的Transition指向Start,流程实例启动后,会离开开始活动.

结束活动/End

代表流程的结束,一个流程图中可以有0个或多个End.比如:

如果没有End,则执行完没有Transition的活动后,流程就结束了.

如果有多个End,则执行到其中任意一个End,流程就结束了.

任务活动/Task

代表在这里需要有一个人来做事情,事情做完后流程才能继续向后执行.

指定任务办理人时,可以使用assignee属性来指定.

生成任务时,默认只有这个指定的人才能看到任务和办理这个任务.

判断活动/Decision

使用Decision时要指定一个DecisionHandler的实现类来处理.比如有这么一个流程实例:

如果不大于2000,则部门经理直接办理,超过2000就要找总经理.要进行这个逻辑判断就要使用Decision,建立一个类实现DecisionHandler接口:

@SuppressWarnings("serial")
public class DecisionHandlerImpl implements DecisionHandler {
 
    // 进行计算,得出并返回应使用的连线的名称
    @Override
    public String decide(OpenExecution execution) {
        int money = (Integer) execution.getVariable("报销金额");
        System.out.println("DecisionHandlerImpl.decide() ---> 报销金额=" + money);
 
        if (money > 2000) {
            return "to 总经理审批";
        } else {
            return "to end1";
        }
    }
 
}

我们说了流程变量的生命周期与流程实例的生命周期相同,金额由流程变量带过去.处理器类在Decision的Handler Class属性中指定.

分支/聚合 Fork/Join

Fork与Join要成对地使用.从一个Fork中分出的多个分支一定要再回到同一个Join中去.当流程执行到Fork中时,ProcessInstance会分成多个并行执行的子Execution,因为ProcessInstance继承自Execution,并且是个标记接口,所以说ProcessInstance只是一个概念,它是想表示整个Execution的执行,也就是主线的执行.

public interface ProcessInstance extends Execution {
}

跑题了,回来继续.当流程执行到Fork时,会分成多个并行执行的子Execution,当所有的分支都执行完到达Join的时候,流程才会继续向Join后执行:

上面这个流程实例就是指:当部门经理和总经理都同意的情况下,不管是谁先同意,就继续执行.

状态活动/State

状态活动可以这样理解:如果说Task是等待人来办理的话,那么State就是等待计算机来办理.因为State除了有一个Name的属性外,没有其他的属性了,而且流程执行到State这里会停住,直到你告诉它要继续的时候它才会往后执行.你唯一可以做的就是给它一个"信号".假设有这样一个流程实例:

有两个State,在流程实例启动的时候会遇到State1,然后停住,等待"信号",在上面的时候说过.outcome、signalName、transionName 都是表示Transition的名称.但是与其他活动的行为不同,其他的活动,比如Task,在没有找到相应的Transition时,会抛异常,而State则什么也不做:

// 让流程向后执行一步
@Test
public void singal() {
    // 让指定的Execution离开当前所在的节点,继续向后执行
    String executionId = "test.380007";
 
    // 当只有一条Transition时,会使用这个Transition离开当前活动
    // 如果有多条Transition,但没有指定要用哪一个,则不会离开节点,也不报错。
    // processEngine.getExecutionService().signalExecutionById(executionId);
 
    // 当有多条Transition时,必须要指下要使用的Transition的名称。
    processEngine.getExecutionService().signalExecutionById(executionId, "to state2");
}

上面预定义活动中可以做的任何事情,都可以通过自定义活动来完成.

自定义活动只有两个属性,一个Name,一个Class的全路径名,给它的类要实现ExternalActivityBehaviour接口,假设我要在这个活动中发送邮件,可以这样做:

@SuppressWarnings("serial")
public class ExternalActivityBehaviourImpl implements ExternalActivityBehaviour {
 
    // 当流程执到当前活动时要做的事。
    @Override
    public void execute(ActivityExecution execution) throws Exception {
        // 通过流程变量获取要通知的人和要通知的信息
        String subject = (String) execution.getVariable("subject");
        String[] users = (String[]) execution.getVariable("users");
 
        // 模拟进行通知
        for (String user : users) {
            System.out.println(user + ",今天下午5点有个会议,会议主题为:" + subject + "。");
        }
 
        //  执行完后不要离开,等到调用singal方法时才离开。
        // execution.waitForSignal();
 
        //  使用指定名称的连线离开当前活动。
        // execution.take(transitionName);
 
        //  使用默认的(配置中的第1个)Transition离开当前活动。
        execution.takeDefaultTransition();
 
        // 如果以上的方法都没有调用,默认是执行完后离开当前活动。
    }
 
    // 在外部明确的调用signal方法真正离开当前活动之前要做的事
    @Override
    public void signal(ActivityExecution execution, String signalName, Map parameters) throws Exception {
        System.out.println("---> ExternalActivityBehaviourImpl.signal()");
    }
}

我们只需要在随意覆写execute()方法,就能做自己想做的事情.里面需要用到的数据还是要通过流程变量带过去.

Task的分配方式

方式一:

Task可以通过assignee属性设置办理人,是具体的某人,也可以指定一个流程变量,会使用计算出的结果(结果要是String类型)表示办理人.

方式二:

利用建立一个类实现AssignmentHandler接口,比如:

@SuppressWarnings("serial")
public class AssignmentHandlerImpl implements AssignmentHandler {
 
    @Override
    public void assign(Assignable assignable, OpenExecution execution) throws Exception {
        // 计算出任务的办理人(可能是获取流程变量,也可能是查询数据库,也可以是其他)
        // execution.getVariable(key);
        String userId = "赵六";
 
        // 指定任务的办理人
        assignable.setAssignee(userId);
 
        System.out.println("----> AssignmentHandlerImpl.assign()");
    }
 
}

把最后的结果(String类型)用setAssignee()方法设置办理人.这需要先在xml文件中加上assignment-handler标签,写上全类路径名:

<task name="task1" g="86,175,92,52">
    assignment-handler class="cn.zhangao.AssignmentHandlerImpl">assignment-handler>
    <transition name="to end1" to="end1" g="-47,-17" />
task>

方式三:

直接在程序中指定,userId的类型为字符串:

processEngine.getTaskService().assignTask(taskId, userId);

这三种方式都只能分配给个人,下面三种方式可能分配给组:

方式一:

指定candidate-users属性,可以指定为具体的String(多个人之间用英文的逗号隔开),也可以指定一个流程变量,会使用计算出的结果(要是String类型,多个人之间用逗号隔开)表示候选人.

方式二:

实现AssignmentHandler接口,用assignable.addCandidateUser(userId)方法添加一个组成员(候选人)

方式三:

程序中指定:

processEngine.getTaskService().addTaskParticipatingUser(taskId, userId, Participation.CANDIDATE);

注意,组任务必须要查询组的任务列表才能看到:

// 查询某人的组任务列表(以组的名义去查询)
@Test
public void findGroupTasks() {
    // String userId = "张3";
    String userId = "王5";
 
    // 查询
    // List list = processEngine.getTaskService().findGroupTasks(userId);
    List list = processEngine.getTaskService()//
            .createTaskQuery()//
            .candidate(userId)// 
            .list();
 
    // 显示
    System.out.println("=========== [" + userId + "]的组任务列表 ==========");
    for (Task t : list) {
        System.out.println("id=" + t.getId()//
                + ", name=" + t.getName()// 任务的名称
                + ", assignee=" + t.getAssignee()// 任务的办理人
                + ", createTime=" + t.getCreateTime() // 任务的创建时间
                + ", executionId=" + t.getExecutionId()); // 任务所属的Execution的id
    }
}

在个人里面是看不到的,找到自己的组任务后,可以通过"拾取"任务把任务变为个人任务,这样自己就能办理了:

// 拾取任务
@Test
public void takeTask() {
    String taskId = "450008";
    String userId = "王5";
 
    processEngine.getTaskService().takeTask(taskId, userId);
}

变为个人任务后,在组任务查询中就查不到了.

事件/Event

事件只能自己手动在xml文件中添加.

  1. 在根元素中,或在节点元素中,使用元素指定事件,其中event属性代表事件的类型。
  2. 在中用子元素,指定处理的类,要求指定的类要实现EventListener接口

事件类型:

  • 元素放在根元素()中,可以指定event为start或end,表示流程的开始与结束。
  • 元素放在节点元素中,可以指定event为start或end,表示节点的进入与离开
  • 在Start节点中只有end事件,在End节点中只有start事件。
  • 在元素中直接写,就是配置事件。(因为在这里只有一个事件,所以不用写on与类型)
  • 在元素中还可以配置assign事件,是在分配任务时触发的。


如果本文有任何问题,请及时指出,以免对后来者产生不必要的困扰,不胜感激!

时间: 2024-10-28 16:58:10

jBPM二(表达业务流程)的相关文章

jBPM一(概念及管理控制流程)

工作流(Workflow),就是"业务过程的部分或整体在计算机应用环境下的自动化",它主要解决的是"使在多个参与者之间按照某种预定义的规则传递文档.信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现". 通俗的说,流程就是多个人在一起合作完成某件事情的必要步骤,把步骤变成计算机能理解的形式就是工作流. 工作流管理系统(WfMS,Workflow Management System)的主要功能是通过计算机技术的支持去定义.执行和管理工作流,协调

基于供应链优化策略的企业业务流程重组方案

一.引言 目前经济全球化与网络化已经成为一种潮流,通过计算机和互联网来实现商务活动的国际化.信息化和无纸化,已成为各国商务发展的一种趋势.当今的市场竞争不再是单个企业之间的竞争,而是供应链与供应链之间的竞争,各企业为了适应这一形式的发展.必须扩展市场范围,提高工作效率,建立良好的客户沟通关系,从而降低成本.增加销售,增强企业的核心竞争力,需要按照供应链,对企业的业务流程从根本上进行重新思考,并彻底进行再设计,构建与战略组织相配适的企业流程,用先进的管理技术可以换取效率,使企业业绩的关键指标,如成

影响业务流程重组个人接受的技术

一.相关理论文献 在技术接受研究中,个体如何以及为什么会接受新的信息技术已经成为研究的一个重要方面.不同的理论的主张.看法不同,但又有交叉,Taylor和Todd(1995)将技术接受理论总结为两条研究路线:一条路线是基于社会心理学研究个人行为,如理性行为理论TRA(Theory of Reasoned Action)(Ajzen,Fishbein,1980).计划行为理论TPB(Theory of Planned Behavior)(Ajzen,1985,1991)以及技术接受模型TAM(Te

行业网站的突破点在于业务流程的创新

行业网站已经成为中国电子商务一股重要的力量,也成为中国电子商务细分市场的主体.在迅速增长的过程中,也面临着各种挑战,其中重要的挑战来自阿里巴巴等综合电子商务网站的竞争. 对于行业网站来讲,想在未来激烈的竞争中取得优势,我认为其突破点在于业务流程的创新.即行业网站需要寻找到一种最适合行业自身特点的业务流程,而不只是一味的模仿阿里巴巴模式. 一.行业网站是电子商务细分市场的主体 目前国内电子商务业态从范围来讲,横向发展的主要是综合电子商务网站,比如阿里巴巴等,纵向的垂直细分市场包含有行业网站.地方网

资料分享基于JBPM5.4实战流程引擎开发

问题描述 跟大家分享一份名叫<国内首部基于JBPM5.4实战流程引擎开发(动态表单.模板引擎.公文管理系统)>的教程,该课程是基于贝斯ERP系统中的一个流程管理模块,基于java及JBPM5.4流程引擎技术开发.大家可以下载来看一下,相互学习,下面是详细内容第一课(工作流开发基础-为什么学习工作流)第二课(工作流开发基础-JBPM5.4介绍)第三课(安装和配置JBPM5.4及Eclipse流程插件安装)第四课(使用JBOSS7.1及对JBPM5.4事件学习01)第五课(完成请假案例及定时器事件

客服运营三部曲

业务流程是客服中心维护日常业务运营.保证服务质量的必备管理手段.作为流程管理者,在流程管理工作中不仅需要满足客服中心"服务基数大.业务内容多.跟进周期短.转接逻辑复杂" 的要求,还要应对业务发展及时响应并灵活变动,保证客服业务流程的有效性.敏捷性.全面性. 面对这些管理需求,单例流程梳理或优化是无法有效支持的,只有建立完整全面的客服业务流程体系,才能推动客服业务流程从"分散描述"提升到"系统设计"水平,进而支撑客服中心的运营管理. 客服业务流程体

商业银行大数据战略与规划思考

随着现代科技的不断进步,信息技术呈现出跨越式大发展的格局,以移动互联网.物联网.大数据和云计算等为代表的新技术应用,大幅提高了社会的生产生活效率.移动互联网的应用降低了互联网的接入成本,增加了互联网的覆盖广度和深度,加速了各行业的互联网化进程:物联网的应用让"人与物"."物与物"相联,实现了更加精细化.动态化的生产生活管理,提高了资源利用和生产力水平:以大规模并行计算.人工智能.机器学习等为特征的大数据应用,使得大范围快速分析和智能预测成为可能,将革命性地改变政府机

基于业务的信息系统选型七步法

企业信息化的道路充满荆棘,这固然和中国企业本身http://www.aliyun.com/zixun/aggregation/14054.html">信息技术人才缺乏,信息技术素质低,中国管理软件市场处于成长的混乱期,厂商更多注重短期利益等原因有直接关系,但是未尝就不和企业本身对信息技术选择.实施的方法论有关. 我在1997-2006年期间,有幸参加多家大型企业集团的技术信息化与管理信息化项目建设,对于这段工作的经历,我总结成功的系统选型是面向业务的选型方法论.基于业务的软件选型方法可以很

数字化时代,物流与零售业的正确打开方式

本文讲的是 :  数字化时代,物流与零售业的正确打开方式  ,[IT168 评论]"如果你的居住地突然入驻了亚马逊,那么这里会发生什么样的化学变化呢?" ▲Infor亚太及日本地区解决方案咨询总监 Cas Brentjens 3月21日,在Infor的媒体沟通会上,其亚太及日本地区解决方案咨询总监 Cas Brentjens给出了我们答案.Cas曾在一周前与亚马逊高级总监探讨这个问题,双方认为亚马逊入驻的市场会发生如下变化: ·品牌店路程一小时以内的地价上涨; ·周边人员工资会产生15