工做流(Workflow),就是经过计算机对业务流程自动化执行管理。它主要解决的是“使在多个参与者之间按照某种预约义的规则自动进行传递文档、信息或任务的过程,从而实现某个预期的业务目标,或者促使此目标的实现”。java
1)Activiti介绍
Activiti是一个工做流引擎,activiti能够将业务系统中复杂的业务流程抽取出来,使用专门的建模语言(BPMN2.0)进行定义,业务系统按照预先定义的流程进行执行,实现了业务系统的业务流程由activiti进行管理,减小业务系统因为流程变动进行系统升级改造的工做量,从而提升系统的健壮性,同时也减小了系统开发维护成本。官方网站:https://www.activiti.org/数据库
2)BPMN
BPMN(Business Process Model And Notation)-业务流程模型和符号是由BPMI(Business Process Management Initiative)开发的一套标准的业务流程建模符号,使用BPMN提供的符号能够建立业务流程。segmentfault
Activiti 就是使用BPMN 2.0 进行流程建模、流程执行管理,它包括不少的建模符号,好比:Event 用一个圆圈表示,它是流程中运行过程当中发生的事情。api
一个bpmn图形的例子:异步
1)部署activiti
Activiti是一个工做流引擎(其实就是一堆jar包API),业务系统使用activiti来对系统的业务流程进行自动化管理,为了方便业务系统访问(操做)activiti的接口或功能,一般将activiti环境与业务系统的环境集成在一块儿。ide
2)流程定义
使用activiti流程建模工具(activity-designer)定义业务流程(.bpmn文件)。.bpmn文件就是业务流程定义文件,经过xml定义业务流程。工具
3)流程定义部署
向activiti部署业务流程定义(.bpmn文件)。使用activiti提供的api向activiti中部署.bpmn文件(通常状况还须要一起部署业务流程的图片.png)网站
4)启动一个流程实例(ProcessInstance)
启动一个流程实例表示开始一次业务流程的运行,好比员工请假流程部署完成,若是张三要请假就能够启动一个流程实例,若是李四要请假也启动一个流程实例,两个流程的执行互相不影响,就比如定义一个java类,实例化两个对象同样,部署的流程就比如java类,启动一个流程实例就比如new一个java对象。编码
5)用户查询待办任务(Task)
由于如今系统的业务流程已经交给activiti管理,经过activiti就能够查询当前流程执行到哪了,当前用户须要办理什么任务了,这些activiti帮咱们管理了spa
6)用户办理任务
用户查询待办任务后,就能够办理某个任务,若是这个任务办理完成还须要其它用户办理,好比采购单建立后由部门经理审核,这个过程也是由activiti帮咱们完成了,不须要咱们在代码中硬编码指定下一个任务办理人了。
7)流程结束
当任务办理完成没有下一个任务/结点了,这个流程实例就完成了。
1.安装Activiti Designer插件
在IDEA的File菜单中找到子菜单”Settings”,后面咱们再选择左侧的“plugins”菜单,搜索actiBPM插件,安装成功后以下图所示:
重启IDEA就可使用了
2.数据库表的命名规则
Activiti的表都以ACT_开头。第二部分是表示表的用途的两个字母标识。用途也和服务的API对应。
3.ProcessEngine
工做流引擎,至关于一个门面接口,经过ProcessEngineConfiguration建立processEngine,经过ProcessEngine建立各个service接口。
4.新建流程
1)首先选中存放图形的目录(选择resources下的bpmn目录),点击菜单:New-BpmnFile
2)绘制流程
3)指定任务负责人
4)搭建工做流项目,部署流程定义,参考https://segmentfault.com/a/11...,要将上边绘制的图形即流程定义(.bpmn)部署在工做流程引擎activiti中
/** * 流程定义的部署 * activiti表有哪些? * act_re_deployment 部署信息 * act_re_procdef 流程定义的一些信息 * act_ge_bytearray 流程定义的bpmn文件及png文件 */ @Test public void createDeploy() { RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deployment = repositoryService.createDeployment() .addClasspathResource("diagram/holiday.bpmn")//添加bpmn资源 .addClasspathResource("diagram/holiday.png") .name("请假申请单流程") .deploy(); log.info("流程部署id:" + deployment.getName()); log.info("流程部署名称:" + deployment.getId()); }
执行此操做后activiti会将上边代码中指定的bpm文件和图片文件保存在activiti数据库。
5)启动一个流程实例
流程定义部署在activiti后就能够经过工做流管理业务流程了,也就是说上边部署的请假申请流程可使用了。
针对该流程,启动一个流程表示发起一个新的请假申请单,这就至关于java类与java对象的关系,类定义好后须要new建立一个对象使用,固然能够new多个对象。
对于请假申请流程,张三发起一个请假申请单须要启动一个流程实例,李四发起一个请假单也须要启动一个流程实例。
/** * 启动流程实例: * 前提是先已经完成流程定义的部署工做 * <p> * 背后影响的表: * act_hi_actinst 已完成的活动信息 * act_hi_identitylink 参与者信息 * act_hi_procinst 流程实例 * act_hi_taskinst 任务实例 * act_ru_execution 执行表 * act_ru_identitylink 参与者信息 * act_ru_task 任务 */ @Test public void startProcessInstance() { RuntimeService runtimeService = processEngine.getRuntimeService(); //启动流程实例 ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holiday"); log.info("流程定义ID:" + processInstance.getProcessDefinitionId()); log.info("流程实例ID:" + processInstance.getId()); }
6)任务查询
流程启动后,各各任务的负责人就能够查询本身当前须要处理的任务,查询出来的任务都是该用户的待办任务。
/** * 查询当前用户的任务列表 */ @Test public void findPersonalTaskList() { TaskService taskService = processEngine.getTaskService(); //根据流程定义的key,负责人assignee来实现当前用户的任务列表查询 List<Task> taskList = taskService.createTaskQuery() .processDefinitionKey("holiday") .taskAssignee("张三") .list(); for (Task task : taskList) { System.out.println("-----------------------"); System.out.println("流程实例ID:" + task.getProcessInstanceId()); System.out.println("任务ID:" + task.getId()); System.out.println("任务负责人:" + task.getAssignee()); System.out.println("任务名称:" + task.getName()); } }
7)任务处理
任务负责人查询待办任务,选择任务进行处理,完成任务。
/** * 处理当前用户的任务 * 背后操做的表: * act_hi_actinst * act_hi_identitylink * act_hi_taskinst * act_ru_identitylink * act_ru_task */ @Test public void completeTask() { String processDefinitionKey = "holiday"; TaskService taskService = processEngine.getTaskService(); Task task = taskService.createTaskQuery().processDefinitionKey(processDefinitionKey) .taskAssignee("张三").singleResult(); if(task != null){ //处理任务,结合当前用户任务列表的查询操做的话 taskService.complete(task.getId()); log.info("处理完成当前用户的任务"); }else{ log.info("当前用户暂无任务"); } }
8)查询历史
@Test public void queryHistory() { HistoryService historyService = processEngine.getHistoryService(); RepositoryService repositoryService = processEngine.getRepositoryService(); //查询流程定义 ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery(); String processDefinitionKey = "holiday"; //遍历查询结果 ProcessDefinition processDefinition = processDefinitionQuery.processDefinitionKey(processDefinitionKey) .orderByProcessDefinitionVersion().desc().singleResult(); if (processDefinition != null) { HistoricActivityInstanceQuery query = historyService.createHistoricActivityInstanceQuery(); List<HistoricActivityInstance> list = query.processDefinitionId(processDefinition.getId()) .orderByHistoricActivityInstanceStartTime().asc().list();//排序StartTime for (HistoricActivityInstance ai : list) { System.out.println(ai.getActivityId()); System.out.println(ai.getActivityName()); System.out.println(ai.getProcessDefinitionId()); System.out.println(ai.getProcessInstanceId()); System.out.println("=============================="); } } }