简介:

工作流是开发者迈向更高级的一个阶梯,能够帮助我们在更规范清晰的业务场景下更加高效的实现开发工作。

适用场景:

任何一个中间件的引入都会带来额外的复杂度,如果不能正确的认识和使用她,那么她就是累赘。工作流是一个很庞大的中间层,一般用于企业中台的流程管理,保证流程的清晰规范高效的同时,大大减少了开发的工作量。

当我们需要开发一个多角色参与的业务流程时,我们们就需要工作流,如请假审批流程、会议室申请、物资采购流程、网购从下单到物流跟踪签收整个后台流程等

工作流技术现状:

工作流最初都是基于jboss的jbpm,代表性的是activiti和flowable。activiti开发团队解散重组后,部分activiti核心开发人员开启了flowable项目,原开发人员则推进activiti7版本的开发。

网上能找到的工作流学习资料比较少,目前activiti7分别在5月和6月推出了7.1.0M1和M2版本,flowable也到了6.4.1版本,但事实上这两个目前都是还在开发中的半成品。如果想要使用的话,还是寻求稳定版本较好,activiti的稳定版本有5.22和6.0.0,我在这里以6.0.0版本为例介绍下我的学习过程。

知识基础:

activiti是以BPMN规范为基础的,所以需要了解BPMN的基础知识,这里只作简单介绍。

bpmn通过流程图和用户交互,用工作流自己的表来维护流程数据,其中activiti是28张表,以act_开头,act_hi_是历史记录类表、act_ru_是运行时流程数据维护表。

BPMN基本对象:

事件event: 代表开始和结束,流程图表示为圆

活动Task(activity):代表处理活动的角色,流程图是一个矩形

网关gateway:代表角色的处理选择,决定流程走向,流程图是一个菱形

流向flow:代表流程图走向,流程图是一个单方向的箭头线

活动任务 Task:

userTask 人机交互任务,必须有人参与操作的任务

ServiceTask Task服务任务,机器自动化

SendTask 发送任务,类似于ServiceTask

ReceiveTask 状态任务,一般用户表示活动状态,需要singal进行流转

ManualTask 线下手工执行任务

BusinessRuleTask 业务规则任务

ScriptTask 脚本任务

AbstractTask 抽象任务

网关 Gateways:

parallel Gateway 并行网关 菱形中一个加号,不会解析条件

Exclusive Gateway 排他网关 菱形或者菱形中一个乘号

Inclusive Gateway 包容网关 菱形中一个圆,走完所有符合条件的flow

工作准备:

安装eclipse并安装activiti流程图绘制插件

打开Eclipse -> Help -> Install New SoftWare-> Add

name任意 location:http://www.activiti.org/designer/update/

如果网络不好请架梯子翻墙并反复尝试,网上离线安装的方法我试过了,不可用。

idea玩家可以setting-plugin-actiBPM install下载安装

不过学习阶段不推荐使用idea插件,本人一开始就用的actiBPM,结果画出来的的流程图部署时总是报错,而且actiBPM的表单支持非常糟糕

还有其他的绘图工具如bpmn-js,还在开发中,功能并不完善不推荐

学习开始:

1.流程图工程新建

新建activiti项目:eclipse-文件-新建-其他-activiti-activitiProject

新建activiti空白文件:eclipse-文件-新建-其他-activiti-activitiDiagram

2.使用右侧的画板,画一个简单的审批流程图如图

3.填充流程图信息[重点]

流程图里可以填充的信息选择非常多,每一条信息,在代码中都是有用的,在尝试成功部署运行流程图后,慢慢去理解他每一个配置的意义。此处只展示实现该简单流程需要的配置

3.1文件命名

鼠标点击空白处,填充如下信息,用来命名该bpmn文件的名称和id

3.2userTask审批填充

鼠标点击领导审批矩形框,填充领导审批业务的名称和id

选择属性下的Form-NEW,填写领导审批需要的表单信息,其中type为string,全小写。完成后如图所示

人事审批和重新申请以此类推。

3.3网关flow条件填充

点击领导审批后面的网关指向人事的线,在属性的Main config里填写审批判断条件,此处的tlApprove和之前领导审批Form中的单词大小写要一致

点击该网关指向重新申请的线作同样的修改,其他类推,如图。

填充完毕保存。至此,一个简易的流程就画完了总结下,其实我们必须要填的就两个地方:1.form中xxApprove用于存储用户传给系统的指令(同意/反对)2.网关后面flow的判断条件,写法和jsp一样${xxApprove == flag}

4.搭建一个java工程,部署并运行该流程图

4.1使用idea新建一个普通工程

file-new-project-spring initializr-next...finish;可以把demo改成自己喜欢的名字,如activiti6

4.2添加activiti依赖

在pom文件中添加activiti依赖和h2database依赖

<dependency><groupId>org.activiti</groupId><artifactId>activiti-engine</artifactId><version>6.0.0</version>
</dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><version>1.3.176</version>
</dependency>

4.3添加bpmn文件

在resource目录下新建一个processes目录,将刚刚eclipse中画好的bpmn文件复制进来

4.4添加日志配置文件

在resource目录下新建一个名为logback.xml的文件,输入如下xml配置

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false"><property name="log.dir" scan="true" scanPeriod="30 seconds"/><property name="encoding" value="UTF-8"/><property name="plain" value="%msg%n"/><property name="std" value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/><!-- 控制台输出 --><appender name="stdout" class="ch.qos.logback.core.ConsoleAppender"><encoder><pattern>${plain}</pattern><charset>${encoding}</charset></encoder></appender><!-- 日志输出级别 --><logger name="root"><level value="ERROR"/></logger><logger name="com.example"><level value="DEBUG"/></logger><root><appender-ref ref="stdout" /></root>
</configuration>

4.5新建一个测试类用来部署并运行我们的bpmn文件

package com.example.activiti6.generate;import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.TaskService;
import org.activiti.engine.form.FormProperty;
import org.activiti.engine.impl.form.StringFormType;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;/*** @ClassName demotest* @Description TODO* @Author cheng* @Date 2019/6/23 13:53**/
public class demotest {private static final Logger logger = LoggerFactory.getLogger(demotest.class);public static void main(String[] args) {logger.info("流程启动");//创建流程引擎ProcessEngine processEngine = ProcessEngineConfiguration.createStandaloneInMemProcessEngineConfiguration().buildProcessEngine();logger.info("流程器名称:{};流程器版本号:{}",processEngine.getName(),ProcessEngine.VERSION);//部署流程定义文件RepositoryService repositoryService = processEngine.getRepositoryService();Deployment deploy = repositoryService.createDeployment().addClasspathResource("processes/MyProcess.bpmn").deploy();ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery().deploymentId(deploy.getId()).singleResult();logger.info("流程定义文件名称:{};流程定义文件id:{}",processDefinition.getName(),processDefinition.getId());//启动运行流程ProcessInstance processInstance = processEngine.getRuntimeService().startProcessInstanceById(processDefinition.getId());logger.info("流程实例的定义key:{}",processInstance.getProcessDefinitionKey());//处理流程任务Scanner scanner = new Scanner(System.in);while(processInstance != null && !processInstance.isEnded()){TaskService taskService = processEngine.getTaskService();List<Task> list = taskService.createTaskQuery().list();for (Task task : list) {logger.info("待处理任务:{}",task.getName());List<FormProperty> formProperties = processEngine.getFormService().getTaskFormData(task.getId()).getFormProperties();Map<String,Object> variables = new HashMap<>();for (FormProperty formProperty : formProperties) {String line = null;if(StringFormType.class.isInstance(formProperty.getType())){logger.info("请输入:{}",formProperty.getName());line = scanner.nextLine();variables.put(formProperty.getId(),line);}else{logger.info("您输入的类型不支持:{}",formProperty.getType());}logger.info("您输入的内容是:{}",line);}taskService.complete(task.getId(),variables);//查询当前流程实例processInstance = processEngine.getRuntimeService().createProcessInstanceQuery().processInstanceId(processInstance.getId()).singleResult();}logger.info("待处理任务数量:{}",list.size());}}
}

5.执行流程

执行结果如下图,本次工作流入门体验完毕,下一节将进一步讲解在工作中如何实际使用activiti完成开发任务

本文代码Github地址

Activiti6工作流入门初体验相关推荐

  1. 工作流Activiti初体验—流程撤回【二】

    已经玩工作流了,打算还是研究一下撤回的功能.但是流程图里面并不带撤回的组件,所以需要自己动态改造一下,还是延续上一个流程继续试验撤回功能.<工作流Activiti初体验[一]> 完整流程图 ...

  2. 赛灵思的FPGA入门初体验

    FPGA初体验 最近一段时间做一点图像加速的东西,在对比了CPU.GPU的实现之后,又发现了FPGA用来做图像处理实时性比一般的GPU更高,而且GPU的结构自实现完成后就确定下来了,而FPGA本身作为 ...

  3. 华为云服务器入门初体验

    文章目录 0x00 文章内容 0x01 领取试用服务器 1. 领取服务器 2. 下订单 0x02 服务器初体验 1. 登录服务器 0xFF 总结 0x00 文章内容 领取试用服务器 服务器初体验 0x ...

  4. APICloud入门初体验

    APP快速开发平台APICloud之初体验 借助APICloud开发平台,使用web开发技术制作的APP,和我们使用原生开发的APP,几乎没有任何区别,这是因为除了使用HTML.JS这些web开发技术 ...

  5. JHipster入门初体验

    JHipster入门 前言 微服务是真的太吃电脑配置了,我的电脑16g内存,5个微服务基本干完了,当然idea也占了不少内存.电脑配置不是很行的要谨慎. JHipster创建registry Jhip ...

  6. 我的Go语言学习之旅二:入门初体验 Hello World

    好吧,所有的程序员们都已经习惯了,学习任何一门语言,我们都会以Hello World实例开始我们的学习,我也不例外.先来一个简单的例子 打开编辑器 (可以用记事本,我已经习惯 Notepad++了)输 ...

  7. 理论+实操:docker入门初体验,申请阿里镜像加速器

    文章目录 一:Docker概述 1.1 docker概念: 1.2 docker设计的目标: 1.3 docker的组成: 1.4 docker的使用场景 1.5 docker版本: 二: docke ...

  8. 一个新手菜鸟的JVM 入门初体验

    话说现在jdk已经有好多个版本了,官网楼一眼:https://blogs.oracle.com/java-platform-group/the-arrival-of-java-13 已经13了. 以前 ...

  9. 【日志系统】Loki日志监控 - 入门初体验

    使用Grafana+Loki+Promtail入门级部署分布式日志系统(windows环境)

  10. php的swoole教程,PHP + Swoole2.0 初体验(swoole入门教程)

    PHP + Swoole2.0 初体验(swoole入门教程) 环境:centos7 + PHP7.1 + swoole2.0 准备工作: 一. swoole 扩展安装 1 .下载swoole cd/ ...

最新文章

  1. java编写脚本校验修改密码_java编写一个更改密码校验程序,有两个密码框,一个用于输入新密码,另一个请输入确认密码……...
  2. JavaScript对象的创建
  3. 10个数冒泡排序流程图_C语言 | 冒泡排序
  4. CSS Hack 和向后兼容
  5. 阿里登顶毕马威全球企业创新榜 AliOS引领智能网联汽车产业发展
  6. Python连接Oracle-常见问题
  7. 拓端tecdat|R语言NLP案例:LDA主题文本挖掘优惠券推荐网站数据
  8. SOAPUI安装破解
  9. 小学生学计算机编程实例,用日常生活小例子来教孩子学编程
  10. pygame使用多种方法让背景和人物运动起来
  11. 微信小程序实现登录功能
  12. JS计算两个数组的交集、差集、并集、补集(多种实现方式)
  13. vps mysql_vps mysql自动关闭
  14. TP5在json入库多出来反斜杠
  15. 即将30岁的2020年总结,放眼未来的未雨绸缪
  16. 2021-10-15
  17. Wifi网络共享----Win8内置承载网络
  18. 为什么大学计算机老师不去大公司当程序员说出来你都很难敢相信
  19. LabVIEW控制高速微快门
  20. 使用python-aiohttp搭建微信公众平台

热门文章

  1. PCB Web版SI9000阻抗计算器
  2. IEC 60335-1家用电器的安全标准及安规寿命检测设备
  3. 多出多个虚拟显示器的解决方法
  4. windows虚拟显示器开发(二)WDDM hook(USB转HDMI驱动、USB手写屏开发)
  5. OpenCV人脸识别
  6. vue js代码混淆加密、压缩
  7. 2021第三届长安杯检材一wp
  8. 2021-03-26,拉胯的三条命令,HappyCTFd
  9. 蓝桥杯2019c语言b组试题,2020年7月B组C++蓝桥杯真题试水
  10. 投标文件 医院弱电系统_智慧建筑办公楼弱电系统如何规划设计?需要设计哪些系统?...