JBPM工作流引擎原理「建议收藏」

JBPM工作流引擎原理「建议收藏」1.JBPM工作流引擎是用来做什么的首先要说明的一点是工作流引擎指的并不只是JBPM,JBPM只是工作流引擎的一种。JBPM利用JPDL流程定义语言将现实生活中处理事务的业务流程进行抽象,形成一套业务流程规则,只要处理该项业务就必须按照这个流程规则进行。举一个很简单的例子,就拿看医生来讲,看医生的整个流程必须是先挂号,再看病,再抓药,只要你进行看医生这个业务就必须按照这套流程进行。…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

1.      JBPM工作流引擎是用来做什么的

首先要说明的一点是工作流引擎指的并不只是JBPM,JBPM只是工作流引擎的一种。JBPM利用JPDL流程定义语言将现实生活中处理事务的业务流程进行抽象,形成一套业务流程规则,只要处理该项业务就必须按照这个流程规则进行。举一个很简单的例子,就拿看医生来讲,看医生的整个流程必须是先挂号,再看病,再抓药,只要你进行看医生这个业务就必须按照这套流程进行。说白了,工作流引擎只是将我们人工的处理过程进行了信息化而已,也并不是多么高深的思想。但是JBPM也并不是想我所说的这样简单,毕竟是一套相对来讲比较成熟的技术,它的功能还是十分强大的,它可以用来定义顺序流程结构,选择流程结构(也就是根据条件判断来决定下一步执行哪项任务),以及多任务必须全部完成才能进行到下一步的流程结构。总之,JBPM是将生活中的各种业务处理情况进行抽象所制定出的一套业务处理规则。

2.      JBPM如何应用

使用JBPM工作流引擎一般来讲分为五部分,他们分别是部署流程,创建流程实例,获取当前活动,获取特定用户的任务,以及完成任务。其中,每一部分都是通过一项JBPM服务完成的。下面通过上面的看医生这个流程来讲解如何使用JBPM。

首先来看我们的jpdl文件:

     <?xml version="1.0" encoding="UTF-8"?>  
    <process key="test" name="test" xmlns="http://jbpm.org/4.4/jpdl">  
       <start g="275,16,48,48" name="start1">  
          <transition g="-60,-15" name="挂号" to="进行挂号"/>  
       </start>  
       <task assignee="nurse" g="255,101,92,52" name="进行挂号">  
          <transition g="-69,-20" name="提交到医师" to="医师看病"/>  
       </task>  
       <task assignee="doctor" g="259,186,92,52" name="医师看病">  
          <transition g="-50,-20" name="抓药" to="end1"/>  
       </task>  
       <end g="283,283,48,48" name="end1"/>     
    </process>  

上面的jpdl文件定义好了整个看医生的流程,它由四个节点组成,开始节点,进行挂号节点,医师看病节点以及结束节点组成。下面我们来看上面提到的具体的五部分都是怎样进行的:

     public class seeDoctor extends TestCase {  
      
        /** 
         * 部署流程 
         */  
        public void deploy(){  
            //创建流程引擎  
            ProcessEngine processEngine = Configuration.getProcessEngine();  
              
            //创建服务  
            RepositoryService repositoryService = processEngine.getRepositoryService();  
              
            //部署流程  
            repositoryService.createDeployment().addResourceFromClasspath("seeDoctor.jpdl.xml").deploy();  
              
              
        }  
          
        /** 
         * 创建流程实例 
         */  
        public void createInstance(){  
            //创建流程引擎  
            ProcessEngine processEngine = Configuration.getProcessEngine();  
              
            ExecutionService executionService = processEngine.getExecutionService();  
              
            ProcessInstance processInstance = executionService.startProcessInstanceByKey("seeDoctor");  
              
            System.out.println("流程实例ID===============" + processInstance.getId());  
        }  
          
        //查询流程实例当前所在节点  
            public void getCurrentActivity(){  
                ProcessEngine processEngine = Configuration.getProcessEngine();  
                ExecutionService executionService = processEngine.getExecutionService();  
                String activityName = executionService.createProcessInstanceQuery().processInstanceId("seeDoctor.10001").uniqueResult().findActiveActivityNames().toString();  
                System.out.println("当前任务所在节点======" + activityName);  
            }  
          
        /** 
         * 获取对应人员的任务 
         */  
        public void getTask(){  
            ProcessEngine processEngine = Configuration.getProcessEngine();  
            TaskService taskService = processEngine.getTaskService();  
            List<Task> tasks = taskService.findPersonalTasks("nurse");  
            Task task = tasks.get(0);  
            System.out.println("任务数量===" + tasks.size() );  
            System.out.println("任务名词===" + task.getActivityName());  
            System.out.println("任务人员===" + task.getAssignee() + "任务ID===" + task.getId());  
        }  
          
          
          
        //完成任务  
        public void completeTask(){  
            ProcessEngine processEngine = Configuration.getProcessEngine();  
            TaskService taskService = processEngine.getTaskService();  
            taskService.completeTask("20001");  
        }  
    }  

下面我们来一次讲解每个部分所完成的主要功能。

Deploy()部署流程的作用顾名思义,就是部署一个已经制定好的jpdl文件,它的作用类似一个具有版本号的类,流程实例就是这个流程的实例化。在jpdl文件中我们通常通过指定key值来区分所部署的各个流程,如果key相同则规定创建流程实例时按最高版本进行实例化。

 

createInstance()创建流程实例就是根据key值来确定实例化哪个流程,如果有多个流程的key相同则取最高版本。

 

getCurrentActivity()查询流程实例当前所在节点。该函数的作用在于根据流程实例ID,来获取该流程实例当前执行到了哪个节点,如本例中的流程实例有进行挂号和医师看病两个节点,该函数就是用来确定当前流程实例执行到了进行挂号还是医师看病环节。

 

getTask()函数中,之所以用Task task = tasks.get(0)语句来取得第一个任务是因为可能有多个完全不同的流程实例中都有一个为nurse的角色名字,假如恰好出现了这种情况则该函数会取出所有流程实例中角色名称为nurse的任务。

 

completeTask()完成任务,该函数的作用比较清晰就是根据任务ID,将该任务结束,然后进入到下一节点中,比如当前所在任务节点是进行挂号,该任务ID是10001,则完成该任务后,则会自动进入到医师看病这个节点,当完成医师看病这个任务后则会自动进入到end节点,也就是完成了整个流程。

 

3.      JBPM中每个服务所对应的数据库表。

在上面的代码中我们可以很明显的看出在每一部分中都对应着一个Service,也就是一个服务,而所有的服务都是由JBPM引擎来创建的。

在部署流程环节,它所对应的是RepositoryService服务,当部署完流程后,在jbpm4_deployment中会插入一条部署流程记录,同时在jbpm4_deployprop表中会记录该流程的详细信息。

 

在创建流程实例环节,所对应的的是ExecutionService服务,该服务可以根据流程的key值用来启动一个具体的流程实例。启动一个具体的流程实例后会在jbpm4_execution表中插入一条流程实例记录。

 

getCurrentActivity()获取当前流程实例环节对应的也是ExecutionService,它操作的表同样是jbpm4_execution,但是该服务对该表进行的查询操作而并非插入操作,根据流程实例ID来查询出该流程实例当前所在的节点。

 

getTask()获取对应人员的任务环节对应的是TaskService服务,该服务的作用是获取特定角色名的人员的所有任务,它所操作的表示jbpm4_task表,该表所存储的是各个实例的当前任务,所以根据角色名所查询出的很可能是不同实例的相同角色名对应的所有任务。

 

最后一个是completeTask()环节,该环节对应的同样是TaskService服务,它的作用也十分的单一,就是根据任务ID来结束任务,使得流程实例进入到下一个节点。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/195683.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • gmap绘制路径_cad画可见点

    gmap绘制路径_cad画可见点将在地图上用鼠标左键点击的点绘制出来(两点之间用直线连接),并且能够随地图一起实现等比例缩放和拖拽。GMap主要涉及到几个坐标的转换:经纬度与GPoint的转换:GPoint是gMapControl控件坐标,坐标原点(0,0)位于控件的左上角,这个转换用函数FromLatLngToLocal()完成。GPoint与经纬度的转换:将控件坐标转换成经纬度,用函数FromLocalToL

    2022年10月25日
    0
  • linux 添加磁盘 LVM扩容步骤「建议收藏」

    linux 添加磁盘 LVM扩容步骤「建议收藏」LinuxLVM扩容一般步骤以centos7.8为例准备工作:添加硬盘完成硬盘添加,虚拟机重启执行lsblk就可以看到新添加硬盘不重启服务器识别新添加硬盘ls/sys/class/scsi_host/echo”—“>/sys/class/scsi_host/host*/scan具体如下#查看是否有新加硬盘lsblkfdisk-l对新硬盘分区fdisk/dev/sdbn#新建分区p#选择逻辑分区1

    2022年6月20日
    25
  • javascript中onclick(this)用法和onclick(this.value)用法介绍

    javascript中onclick(this)用法和onclick(this.value)用法介绍

    2021年11月3日
    42
  • 字典树的数据结构_数据结构快速排序

    字典树的数据结构_数据结构快速排序本文主要包括以下内容:Trie字典树的基本概念Trie字典树的基本操作插入查找前缀查询删除基于链表的Trie字典树Set性能对比LeetCode相关线段树的问题LeetCode第208号问题LeetCode第211号问题LeetCode第677号问题Trie字典树的基本概念上一篇我们介绍了线段树(SegmentTree),本文主要介绍Trie字典树…

    2022年9月6日
    0
  • 《FFmpeg从入门到精通》读书笔记(三)

    《FFmpeg从入门到精通》读书笔记(三)写在前面2019.06.20第四章知识点(未进行排版,暂未加入硬编解码部分)FFmpeg转码FFmpeg软编码H.264与H.265FFmpeg本身不支持H.264的编码器,是由FFmpeg的第三方模块对其进行支持,当前常用的编码器为x264,所支持的像素格式主要包括以下几种(使用ffmpeg-hencoder=libx264进行查询)Encoderlibx264[l…

    2022年6月26日
    32
  • WPF是什么_wpf documentviewer

    WPF是什么_wpf documentviewer项目中要用到一个数据分页栏,虽然自己没有实现过,但凭经验感觉它和ListBox/ListView有关。于是去网上搜了下WPF数据分页栏,果然很多实现都用到了ListView。于是拣了一种比较简单的实现学习,其中包含下面代码:ListView.View的标签内出现了GridView。在我印象中Grid是网格式的,而List是列表式的,所以我很好奇两者为什么可以混到一起。当然从类的关系上来看,应该是两者都继承了一个共同的父类。那么为了能使用起来更“自如”,对GridView有个系统的了解,还是有必要学习一

    2022年9月2日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号