热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

工作流activiti插件的使用

2019独角兽企业重金招聘Python工程师标准1、因为我用的是eclipse,所以介绍一下eclipse安装activiti的方法,help——

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

1、因为我用的是eclipse,所以介绍一下eclipse安装activiti的方法,help——>Install new software,如下图:

点击add

会出现如下图:

安装图示输入,点击ok,然后finish,等待安装完成。

2、使用

创建一个项目:新建MyProcess.bpmn文件,代码如下:



activiti视图如下:

pom文件需要添加如下几个包:

org.activitiactiviti-engine5.21.0org.activitiactiviti-spring5.21.0org.springframeworkspringorg.activitiactiviti-diagram-rest5.21.0org.springframeworkspringorg.activitiactiviti-modeler5.21.0org.springframeworkspring

activiti有两种监听器,分别是:ExecutionListern主要用于流程的开始、结束和连线的监听,共有三个值:"start"、"end"、"take",其中start和end用于整个流程的开始和结束,take用于连线。TaskListern主要用于节点的监听,共有四个事件:分别是:"create"、"assignment"、"complete"、"delete",当流转到这个节点是触发create事件,当被委托是触发assignment事件,当事件完成时, 因为activity会删除相应数据表中的节点信息所以会同时触发complete和delete事件。

项目中用到的四个监听器代码如下:

/***@description executionListern主要用于流程的开始、结束和连线的监听* 共有三个值:"start"、"end"、"take"。* 其中start和end用于整个流程的开始和结束,take用于连线*@auth panmingshuai*@time 2018年4月5日下午8:59:16* */public class MyExecutionListern implements ExecutionListener{/*** */private static final long serialVersionUID = 1L;@Overridepublic void notify(DelegateExecution execution) throws Exception {//得到现在事件阶段的值,用"start".endsWith(eventName)来判断String eventName = execution.getEventName();if("start".endsWith(eventName)){System.out.println("-------------------流程开始-------------------");} else if("end".equals(eventName)){System.out.println("-------------------流程结束-------------------");}}
}

/***@description *@auth panmingshuai*@time 2018年4月5日下午11:18:24* */public class MyTaskListernBegin implements TaskListener {/*** */private static final long serialVersionUID = 1L;@Overridepublic void notify(DelegateTask delegateTask) {//得到现在事件阶段的值,用"create".endsWith(eventName)来判断String eventName = delegateTask.getEventName();if("create".equals(eventName)){System.out.println("-------------------分组任务开始---------------");//指定组任务审核人员delegateTask.addCandidateUser("ming1");delegateTask.addCandidateUser("ming2");} else if("complete".equals(eventName)){System.out.println("-------------------分组任务结束---------------");}}}

/***@description taskListern主要用于节点的监听* 共有四个事件:分别是:"create"、"assignment"、"complete"、"delete"。* 当流转到这个节点是触发create事件,当被委托是触发assignment事件,当事件完成时,* 因为activity会删除相应数据表中的节点信息所以会触发complete和delete事件*@auth panmingshuai*@time 2018年4月5日下午8:59:16* */public class MyTaskListernGroup implements TaskListener {/*** */private static final long serialVersionUID = 1L;@Overridepublic void notify(DelegateTask delegateTask) {//得到现在事件阶段的值,用"create".endsWith(eventName)来判断String eventName = delegateTask.getEventName();if("create".equals(eventName)){System.out.println("-------------------分组任务开始---------------");//指定组任务审核人员delegateTask.addCandidateUser("ming1");delegateTask.addCandidateUser("ming2");} else if("complete".equals(eventName)){System.out.println("-------------------分组任务结束---------------");}}}

/***@description *@auth panmingshuai*@time 2018年4月5日下午9:44:16* */public class MyTaskListernOwern implements TaskListener {/*** */private static final long serialVersionUID = 1L;@Overridepublic void notify(DelegateTask delegateTask) {//得到现在事件阶段的值,用"create".endsWith(eventName)来判断String eventName = delegateTask.getEventName();if("create".equals(eventName)){System.out.println("-------------------个人任务开始---------------");//添加个人任务delegateTask.setOwner("ming1");} else if("complete".equals(eventName)){System.out.println("-------------------个人任务结束---------------");}}}

接下来是activiti的配置,因为activiti需要操作数据表,因此如果要使用activiti必须要配置数据库连接池和事物管理:

对于其中activiti的服务接口的作用如下:

RepositoryService                    管理流程定义

RuntimeService                        执行管理,包括启动、推进、删除流程实例等操作

TaskService                                任务管理

HistoryService                            历史管理(执行完的数据的管理)

具体使用时需要注入相应的接口:

当然可以不使用这些接口使用processEngine的各种get方法也可以,只是不怎么方便:

3、具体的业务使用:

3.1、首先如果要使用工作流,必须先部署流程:

// 部署流程,只要是符合BPMN2规范的XML文件,理论上都可以被ACTIVITI部署Deployment deployment = repositoryService.createDeployment().addClasspathResource("org/pan/activity/bpmn/MyProcess.bpmn").deploy();System.out.println("deployment: id: " + deployment.getId() + "----- name: " + deployment.getName());return "发布成功";

注:项目启动时,activiti会自动在你连接的数据库生成它所需要的数据表,都是以act_打头的。

一般如果没改流程图的话,也没改数据库的话,只用部署一次就够了。

现在假设一个人提交了一个申请过来,怎么给他一个流程的实例呢?如下:

//开启流程时设置的变量是全局变量Map variables &#61; new HashMap<>();variables.put("shuai", "haha");// 开启流程&#xff0c;myprocess是流程的ID&#xff0c;每个流程图都有自己专属的id&#xff0c;businessid代表每个具体的业务流程ProcessInstance processInstance &#61; runtimeService.startProcessInstanceByKey("myProcess", businessId, variables);Task activityTask &#61; taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskDefinitionKey(processInstance.getActivityId()).singleResult();System.out.println("processInstance: id: " &#43; processInstance.getId() &#43; "----- activityTaskId: " &#43; activityTask.getId());return "开启成功";

这便开启了一个专属的流程实例给某一个业务&#xff0c;值得注意的是processInstance.getId()这个id是activiti自己生成的id&#xff0c;businessId是我们自己的业务id&#xff0c;但是这个可以不用设置&#xff0c;这看项目的需要&#xff0c;我们可以拥有自己的业务申请表&#xff0c;但是也可以把申请的内容放到variables中&#xff0c;需要的时候再查出来&#xff0c;这样就不用再建立自己的申请表了。

流程开始了就需要处理任务了&#xff0c;但是有谁来处理任务呢&#xff1f;

上面的监听器里其实就有代码&#xff0c;需要注意的是当任务的creat事件被触发时设置处理人&#xff0c;设置的处理人也只能处理这个任务&#xff0c;当然还有其他设置处理人的方式&#xff0c;但是我觉得这种方式最好。另外delegateTask.addCandidateUser("ming1");这个是设置组任务处理人的。 

delegateTask.setOwner("ming1");这个是设置个人任务的。所谓的组任务是指这个组里的人都会看到这个任务&#xff0c;个人任务是指只有这个人会看到这个任务。

任务处理人设置好了&#xff0c;那一个人怎么看到自己的任务呢&#xff1f;

// 个人任务查询List taskList &#61; taskService.createTaskQuery().taskAssignee(userName).list();for(Task task : taskList){System.out.println("assignee: " &#43; task.getAssignee() &#43; "---- taskName:" &#43; task.getName() &#43; "---- taskId: " &#43; task.getId());}return taskList.size() &#43; "";

// 组任务查询List taskList &#61; taskService.createTaskQuery().taskCandidateUser(userName).list();for(Task task : taskList){System.out.println("assignee: " &#43; task.getAssignee() &#43; "---- taskName:" &#43; task.getName() &#43; "---- taskId: " &#43; task.getId());}return taskList.size() &#43; "";

需要注意的一点是组任务查询时&#xff0c;只要是这个组的组员的人都会看到所有的组任务&#xff0c;但是组任务怎么确定是谁来处理的这个任务呢&#xff1f;这个时候就需要将这个任务指定了&#xff0c;比如说一个组员说这个任务归他了&#xff0c;那个我们就得把任务派发给他&#xff0c;不然不知道是谁搞定的。如下指定&#xff1a;

taskService.claim(taskId, userName);

好了任务也查好了&#xff0c;我该怎么处理呢&#xff1a;

String val &#61; (String) taskService.getVariable(taskId, "isTrue");String shuai &#61; (String) taskService.getVariable(taskId, "shuai");System.out.println(shuai);System.out.println(val);//这里设置的变量是局部变量&#xff0c;只对下一个节点有用Map variables &#61; new HashMap<>();variables.put("isTrue", isTrue);taskService.complete(taskId, variables);return "任务&#xff1a;" &#43; taskId &#43; " 完成";

这里的getVariable方法是获取从上一个节点传过来的参数&#xff0c;taskService调用complete方法完成节点&#xff0c;这个时候会触发该节点的complete和delete事件以及下一个节点的create事件。complete方法中的variables是传到下一个节点的参数。需要特别注意的是&#xff0c;启动流程实例时startProcessInstanceByKey方法中的variables参数是全局的&#xff0c;你可以在任意一个节点调到他们的值。其中有一个用处就是&#xff1a;比如你要限制一个申请被打回的次数&#xff0c;你可以用它。

好了任务完成了&#xff0c;我们怎么看这个流程走到了哪里呢&#xff1f;

ProcessInstance processInstance &#61; runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(businessId).singleResult();Task activityTask &#61; taskService.createTaskQuery().processInstanceId(processInstance.getId()).taskDefinitionKey(processInstance.getActivityId()).singleResult();System.out.print("----- activityTaskName: " &#43; activityTask.getName());System.out.println("----- isEnded:" &#43; processInstance.isEnded());return "查询成功";

其中activityTask即为当前流程所在的任务节点。

那怎么查一个任务经历了哪些节点呢&#xff1f;

HistoricProcessInstance processInstance &#61; historyService.createHistoricProcessInstanceQuery().processInstanceBusinessKey(businessId).singleResult();List taskInstances &#61; historyService.createHistoricTaskInstanceQuery().processInstanceId(processInstance.getId()).orderByTaskCreateTime().asc().list();for(HistoricTaskInstance taskInstance : taskInstances){System.out.print("taskId:" &#43; taskInstance.getId());System.out.print("---taskName:" &#43; taskInstance.getName());System.out.print("---assignee:" &#43; taskInstance.getAssignee());System.out.print("---startTime:" &#43; taskInstance.getStartTime());System.out.print("---endTime:" &#43; taskInstance.getEndTime());System.out.println("---duration:" &#43; taskInstance.getDurationInMillis());}return "查询成功";

怎么查一个人处理了哪些任务呢&#xff1f;

List taskInstances &#61; historyService.createHistoricTaskInstanceQuery().taskAssignee(userName).list();for(HistoricTaskInstance taskInstance : taskInstances){System.out.print("taskId:" &#43; taskInstance.getId());System.out.print("---taskName:" &#43; taskInstance.getName());System.out.print("---assignee:" &#43; taskInstance.getAssignee());System.out.print("---startTime:" &#43; taskInstance.getStartTime());System.out.print("---endTime:" &#43; taskInstance.getEndTime());System.out.println("---duration:" &#43; taskInstance.getDurationInMillis());}

基本上一个项目中就用到了这些流程的功能&#xff0c;基本满足了&#xff0c;完毕


转:https://my.oschina.net/u/3534905/blog/1790618



推荐阅读
  • 本文将详细介绍如何在Mac上安装Jupyter Notebook,并提供一些常见的问题解决方法。通过这些步骤,您将能够顺利地在Mac上运行Jupyter Notebook。 ... [详细]
  • 为了确保iOS应用能够安全地访问网站数据,本文介绍了如何在Nginx服务器上轻松配置CertBot以实现SSL证书的自动化管理。通过这一过程,可以确保应用始终使用HTTPS协议,从而提升数据传输的安全性和可靠性。文章详细阐述了配置步骤和常见问题的解决方法,帮助读者快速上手并成功部署SSL证书。 ... [详细]
  • Spring框架中的面向切面编程(AOP)技术详解
    面向切面编程(AOP)是Spring框架中的关键技术之一,它通过将横切关注点从业务逻辑中分离出来,实现了代码的模块化和重用。AOP的核心思想是将程序运行过程中需要多次处理的功能(如日志记录、事务管理等)封装成独立的模块,即切面,并在特定的连接点(如方法调用)动态地应用这些切面。这种方式不仅提高了代码的可维护性和可读性,还简化了业务逻辑的实现。Spring AOP利用代理机制,在不修改原有代码的基础上,实现了对目标对象的增强。 ... [详细]
  • 掌握Android UI设计:利用ZoomControls实现图片缩放功能
    本文介绍了如何在Android应用中通过使用ZoomControls组件来实现图片的缩放功能。ZoomControls提供了一种简单且直观的方式,让用户可以通过点击放大和缩小按钮来调整图片的显示大小。文章详细讲解了ZoomControls的基本用法、布局设置以及与ImageView的结合使用方法,适合初学者快速掌握Android UI设计中的这一重要功能。 ... [详细]
  • 基于Node.js的高性能实时消息推送系统通过集成Socket.IO和Express框架,实现了高效的高并发消息转发功能。该系统能够支持大量用户同时在线,并确保消息的实时性和可靠性,适用于需要即时通信的应用场景。 ... [详细]
  • Spring – Bean Life Cycle
    Spring – Bean Life Cycle ... [详细]
  • 在 Ubuntu 中遇到 Samba 服务器故障时,尝试卸载并重新安装 Samba 发现配置文件未重新生成。本文介绍了解决该问题的方法。 ... [详细]
  • 大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式
    大类|电阻器_使用Requests、Etree、BeautifulSoup、Pandas和Path库进行数据抓取与处理 | 将指定区域内容保存为HTML和Excel格式 ... [详细]
  • MATLAB字典学习工具箱SPAMS:稀疏与字典学习的详细介绍、配置及应用实例
    SPAMS(Sparse Modeling Software)是一个强大的开源优化工具箱,专为解决多种稀疏估计问题而设计。该工具箱基于MATLAB,提供了丰富的算法和函数,适用于字典学习、信号处理和机器学习等领域。本文将详细介绍SPAMS的配置方法、核心功能及其在实际应用中的典型案例,帮助用户更好地理解和使用这一工具箱。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 在处理遗留数据库的映射时,反向工程是一个重要的初始步骤。由于实体模式已经在数据库系统中存在,Hibernate 提供了自动化工具来简化这一过程,帮助开发人员快速生成持久化类和映射文件。通过反向工程,可以显著提高开发效率并减少手动配置的错误。此外,该工具还支持对现有数据库结构进行分析,自动生成符合 Hibernate 规范的配置文件,从而加速项目的启动和开发周期。 ... [详细]
  • 本文探讨了利用Java实现WebSocket实时消息推送技术的方法。与传统的轮询、长连接或短连接等方案相比,WebSocket提供了一种更为高效和低延迟的双向通信机制。通过建立持久连接,服务器能够主动向客户端推送数据,从而实现真正的实时消息传递。此外,本文还介绍了WebSocket在实际应用中的优势和应用场景,并提供了详细的实现步骤和技术细节。 ... [详细]
  • 技术分享:深入解析GestureDetector手势识别机制
    技术分享:深入解析GestureDetector手势识别机制 ... [详细]
  • 在尝试对从复杂 XSD 生成的类进行序列化时,遇到了 `NullReferenceException` 错误。尽管已经花费了数小时进行调试和搜索相关资料,但仍然无法找到问题的根源。希望社区能够提供一些指导和建议,帮助解决这一难题。 ... [详细]
  • 深入解析 Android 选择器与形状绘制技术
    本文深入探讨了 Android 中选择器(Selector)与形状绘制(Shape Drawing)技术的应用与实现。重点分析了 `Selector` 的 `item` 元素,其中包括 `android:drawable` 属性的使用方法及其在不同状态下的表现。此外,还详细介绍了如何通过 XML 定义复杂的形状和渐变效果,以提升 UI 设计的灵活性和美观性。 ... [详细]
author-avatar
手机用户2502928203
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有