jpdl 流程定义语言的使用

2024-06-08 00:58

本文主要是介绍jpdl 流程定义语言的使用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、jpdl 流程定义语言的使用

 process(流程)

 transition (连线、转移)

 流转控制活动

•    start (开始活动)

•    end、end-error、end-cancel (结束活动)

•    state (状态活动)

•    task (任务活动)

•    decision (判断活动)

•   fork、join (分支/聚合活动)

1、  process 节点是jpdl 流程描述的根节点,任何流程都要定义

   

         process 节点的属性:

                   name 属性:流程名称 (用于显示

                  key属性:流程关键字(用于查询,通常没有中文),每个流程key应该是不同,如果没有指定key ,将会采用name                              的值(一般用key查询

                            注:同样key的流程,name必须相同

                  version属性:流程版本号每次发布同样key 流程,自动+1,如果指定了version,可能存在冲突问题,冲突就报错

         pdId 规则key加上’-’加上version 例:holiday-1

 

2、   transition连线、转移


作用:用来连接活动节点,完成流程运转

开始节点只能有 一个transition 。结束节点不能用 transition,可以有多个。

常用属性

         name属性:转移连线名称(通常只有一个transition节点,可以不指定name,有些节点具有多个transition,此                               时必须指定name属性,并且name要唯一

         to属性:必须的 指定另一个活动节点名称

注意:nametransition向后一步操作时,需要指定 transitionname

          nametransition向后一步,无需指定流转

 

3、   start活动节点和end活动节点

           start开始节点,在一个活动图中只能有一个开始节点。

           end结束节点,在一个活动图中可以有多个结束节点。

           中止流程代码(不管运行到哪个节点,停止该流程)

                    processEngine.getExecutionService().endProcessInstance(processInstanceId,ProcessInstance.STATE_ENDED);

 

4、   state节点 (状态节点、等待节点)

当执行到state节点时, 和task节点一样需要等待

和task节点区别: task节点需要指定人来完成任务, state节点通常不需要人工干预,就可以继续执行节点

                  例如:报销的时候申请完要经理处理,经理处理就为一个task,处理完后自动转账就为一个state

         Task节点完成时 ,需要调用 taskService.completeTask() 完成任务。

         State 节点完成时,只能调用 executionService.signalExecutionById 向后一步。

 

5、 decision 判断节点

         条件判断节点,主要用于在流程中,可以根据不同条件转向不同分支

         decisition 判断节点也可以制作循环效果

控制流程流转的方向

         方式一通过在<transition>节点中添加 <condition> 节点,通过expr属性执行条件

         变量表达式 #{表达式内容}

<decision name="exclusive1" g="186,221,48,48"><transition name="to end1" to="end1" g="-47,-17"><!-- 如果agreeinfo 是流程变量,值为 agree 结束流程 --><condition expr="#{agreeinfo == 'agree'}"/></transition><transition name="to 重新申请" to="重新申请" g="320,278:-71,-17"><!-- 如果agreeinfo 是流程变量,值为 noagree 重新申请 --><condition expr="#{agreeinfo == 'noagree'}"/></transition></decision>

  简化以上配置也可写为:

   <decision name="exclusive1" g="186,221,48,48" expre="#{agreeinfo}"><transition name="agree" to="end1" g="-47,-17" /><transition name="noagree" to="重新申请" g="320,278:-71,-17" /></decision>

方式二:使用Handler,要实现DecisionHandler接口(更加灵活)

         <decision>元素中配置<handler>元素,通过handlerdecide方法返回String字符串代表跳转transitionname属性

    <decision name="exclusive1" g="186,221,48,48"><handler class="cn.itcast.jbpm.handler.MyDecisionHandler" /><transition name="agree" to="end1" g="-47,-17"/><transition name="noagree" to="重新申请" g="320,278:-71,-17"/></decision>
//判断节点 handler对象
public class MyDecisionHandler implements DecisionHandler {@Overridepublic String decide(OpenExecution openExecution) {// openExecution可以通过getVariable来获得流程中的变量String agreeinfo = (String) openExecution.getVariable("agreeinfo");// 返回 agreeinfo的值 对应的是 <transition> 的name属性return agreeinfo;}
}	

只需要在经理审批后,在变量中保存 agreeinfo信息,通过变量决定流转方向

         注:推荐使用方式二,灵活性更好,可以在handler中写入代码逻辑。

6、 fork 分支/ join 聚合 节点

         fork和join必须成对出现,用来解决业务流程中并发活动问题

         注:只有fork中所有并发活动都完成,才能继续执行,如果有一个并发活动没出来都需要等待。 fork结束后,必须join

   <task name="购物" g="181,82,92,52"><transition name="to fork1" to="fork1" g="-53,-17"/></task><!--分支--><fork name="fork1" g="207,143,48,48"><transition name="to 收钱" to="收钱" g="-47,-17"/><transition name="to 送货" to="送货" g="-47,-17"/></fork><task name="收钱" g="83,209,92,52"><transition name="to join1" to="join1" g="-53,-17"/></task><task name="送货" g="306,210,92,52"><transition name="to join1" to="join1" g="-53,-17"/></task><!—合并--><join name="join1" g="206,274,48,48"><transition name="to end1" to="end1" g="-47,-17"/></join>

7 task节点(最常用的节点) ----任务节点

1) 个人任务

第一种 : <task assignee=”指定任务负责人”>

                    <task assignee="#{employee}">  通过变量 employee 设置该任务负责人, 需要手动添加变量

第二种 : <task>

                            <assignment-handler class=””> 通过handler程序,指定任务负责人

                   编写类实现 AssignmentHandler接口

//通过 handler 指定 个人任务 负责人
public class MyPersonalTaskAssignmentHandler implements AssignmentHandler {@Override// assignable 为任务 指定负责人  、 openExecution 获得流程变量public void assign(Assignable assignable, OpenExecution openExecution)throws Exception {assignable.setAssignee("王五");//改变负责人为王五}
}
第三种 : 通过taskService的assignTask方法,传入(任务id, 负责个人)即可。
处理流程:执行到task节点,查询我的个人任务 taskService.findPersonalTasks(userId);通过task.getId()获得办理任务的编号,  再通过taskService.completeTask(task.getId());来完成任务TaskService taskService = processEngine.getTaskService();// 查询 jbpm4_task 条件 assignee字段List<Task> tasks = taskService.findPersonalTasks(userId);for (Task task : tasks) {System.out.println("编号:" + task.getId());System.out.println("名称: " + task.getName());// 办理任务taskService.completeTask(task.getId());}// 改变任务负责人,可通过TaskService的assignTask方法processEngine.getTaskService().assignTask("30002", "赵六");

2) 组任务

         存在一个任务,任务由指定一组人来完成,组内每个人都有完成任务的能力将任务交给一组人来负责

例如: 公司所有员工都有请假的权利 ----- 需要将公司所有员工放入一个组,进行管理

常见操作流程:先根据用户查询组任务 processEngine.getTaskService().findGroupTasks(userId);

                            对组任务进行拾取操作,组任务被拾取后变为个人任务 taskService.takeTask(taskid, user);

                            可以完成个人任务 taskService.completeTask …

                            改变任务负责人 taskService.assignTask(taskId, userId)  ---- 如果userId为null任务将重新变为组任务

                            (组任务和个人任务查询是分开的

第一种 : 通过<task>元素的 candidate-users 属性或者 candidate-groups 属性都可以设置多个人负责组任务

         数据表的变化:在jbpm4_task插入任务数据, 向jbpm4_participation 存入组内用户

candidate-users<task  candidate-users="张三,李四,王五">

// 组任务 (candidate-users 指定组内负责人)
public void demo2() {Configuration configuration = new Configuration();ProcessEngine processEngine = configuration.buildProcessEngine();// 发布RepositoryService repositoryService = processEngine.getRepositoryService();repositoryService.createDeployment().addResourceFromClasspath("holiday2.jpdl.	xml").deploy();// 启动processEngine.getExecutionService().startProcessInstanceByKey("holiday2");String userId = "李四";// 通过findGroupTasks查询李四的组任务List<Task> list = processEngine.getTaskService().findGroupTasks(userId);// 拾取任务,也就是李四完成这个任务,这是组任务就变成个人任务了processEngine.getTaskService().takeTask("8", userId);// 如果李四完成不了任务了,也可改变任务负责人(如果userId为null任务将重新变为组任务)processEngine.getTaskService().assignTask("8", "小丽");
}
candidate-groups(<task candidate-groups="myusers">)创建组// 组任务 (candidate-groups 指定组)
public void demo3() {Configuration configuration = new Configuration();ProcessEngine processEngine = configuration.buildProcessEngine();// 发布RepositoryService repositoryService = processEngine.getRepositoryService();repositoryService.createDeployment().addResourceFromClasspath("holiday4.jpdl.	xml").deploy();// 通过IdentityService创建组IdentityService identityService = processEngine.getIdentityService();identityService.createGroup("myusers"); // 建组//创建组员createUser(userid,givenName,familyNames)identityService.createUser("张三", "张三", "张"); identityService.createUser("李四", "李四", "李"); //通过createMembership将组员加入identityService.createMembership("张三", "myusers");identityService.createMembership("李四", "myusers");// 启动流程processEngine.getExecutionService().startProcessInstanceByKey("holiday4");
}	
数据表的变化:在 jbpm4_id_group 存放组信息 、jbpm4_id_user 存放用户 、jbpm4_id_membership 存放关系 第二种:通过AssignmentHandler指定负责人 (重点)
//为任务 指定组负责人
public class MyGroupTaskAssignmentHandler implements AssignmentHandler {@Overridepublic void assign(Assignable assignable, OpenExecution openExecution)throws Exception {// 使用 candidate-users方式assignable.addCandidateUser("张三");assignable.addCandidateUser("李四");assignable.addCandidateUser("王五");// 使用candidate-groups 方式// 添加组创建代码 ---- 仍需另外使用 IdentityService创建组assignable.addCandidateGroup("myusers");}
}

第三种:直接使用 TaskService 为任务添加组用户

         方法:addTaskParticipatingUser(taskId, userId, participationType)

                    addTaskParticipatingGroup(taskId,groupId, participationType)

 

3) 泳道 swimlanes

         在UML 活动图中,通过泳道来描述一类用户和活动节点之间关系,从泳道得知哪些活动是属于哪类用户的 !

         JBPM的泳道解决问题,某个用户或者某组用户,在JBPM流程中的连续操作。

举例:张三填写请假条,经理没批(请假原因不详细), 必须由张三补充请假理由。而原来的组管理中,如果经理没有批准        请假,回到重新申请请假的环节,这是又变成了组任务,张三、李四等人都可以完成,显然不符合实际,泳道的作用       就是解决这种问题的。

泳道支持的三个属性:<swimlane  name=" "  assignee=" "  candidate-groups=" "  candidate-users=" "></swimlane>

         assignee 指定泳道属于哪一个人

         candidate-groups、candidate-users 指定泳道属于哪一组人

作用:确保整个流程多个活动节点由一个人或者一组人来完成

 

二、 自定义活动节点和事件(了解)

1、 自定义节点通过custom 元素定义

         custome元素 必须指定class属性,作为运行的类,这个类要实现ExternalActivityBehaviour接口

         覆盖的方法:1):execute(ActivityExecution),节点的功能代码

                               2):signal(ActivityExecution, String, Map),在当前节点等待时,外部发信号时的行为

         注:默认情况下,自定义节点无停留效果 ,execute会执行,signal不会执行 (signal 必须先等待,在离开前执行)

在execute()方法中,可以调用以下方法对流程进行控制

     1):ActivityExecution.waitForSignal(),在当前节点等待,等待结束后就会执行signal方法了。

     (2):ActivityExecution.takeDefaultTransition(),使用默认的Transition离开,当前节点中定义的第一个为默认的。

     (3):ActivityExecution.take(StringtransitionName),使用指定的Transition离开

     (4):ActivityExecution.end(),结束流程实例

备注:如果自定义节点 实现ActivityBehaviour 接口,就无需等待了, 只需要覆盖execute方法。

 

2 、event事件对象的使用

在根元素中,或在节点元素中,使用<on event=“”>元素指定事件,其中event属性代表事件的类型

在<on>中用子元素<event-listener class="EventListenerImpl" /> 为事件绑定一个监听器,当事件触发时,监听器会得到执行。

事件类型:

(1):<on>元素放在根元素(<process>)中,可以指定event为start或end,表示流程的开始与结束。

(2):<on>元素放在节点元素中,可以指定event为start或end,表示节点的进入与离开

(3):在Start节点中只有end事件,在End节点中只有start事件。

(4):在<transition>元素中直接写<event-listener class=“”>,就是配置事件。(因为在这里只有一个事件,所以不用写on与         类型)

          注:编写一个类实现EventListener接口,覆盖notify方法来编写监听器代码

(5):在<task>元素中还可以配置assign事件,是在分配任务时触发的。





这篇关于jpdl 流程定义语言的使用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1040799

相关文章

Security OAuth2 单点登录流程

单点登录(英语:Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。当拥有这项属性时,当用户登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

使用SecondaryNameNode恢复NameNode的数据

1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

Hadoop数据压缩使用介绍

一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

零基础学习Redis(10) -- zset类型命令使用

zset是有序集合,内部除了存储元素外,还会存储一个score,存储在zset中的元素会按照score的大小升序排列,不同元素的score可以重复,score相同的元素会按照元素的字典序排列。 1. zset常用命令 1.1 zadd  zadd key [NX | XX] [GT | LT]   [CH] [INCR] score member [score member ...]

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的