基于springboot的flowable工做流实例实现
flowableUI 建立实例教程 https://www.cnblogs.com/nanstar/p/11959389.htmlhtml
Flowable 中文官网 https://tkjohn.github.io/flowable-userguide/#_deploying_a_process_definition
一、首先建立一空白的个springboot的项目
二、这里是编辑项目名称,我这里写的是flowabledemo
三、这个位置是选择配置的,由于是demo因此我没有选择任何配置
四、这里输入的是输出文件夹的名称,我选择了和项目文件名一致
五、建立完成以后打开项目:
在pomx里添加flowable和mysql依赖(生成数据库要用到),我选择的是MySQL数据库,由于我电脑上有现成的mysqljava
<dependency> <groupId>org.flowable</groupId> <artifactId>flowable-engine</artifactId> <version>6.5.0-SNAPSHOT</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.45</version> </dependency>
六、这时候他会自动下载相应的文件,等待事件有点长,咱们能够去新加一个数据库,已备后用。
新建flowable数据库(数据库名字本身设定)mysql
七、而后在主函数入口部分添加数据库信息(用来自动生成所须要的表,原来的那句话须要注释或删除掉)
// SpringApplication.run(FlowabledemoApplication.class, args); ProcessEngineConfiguration cfg = new StandaloneProcessEngineConfiguration() .setJdbcUrl("jdbc:mysql://localhost:3306/flowable") .setJdbcUsername("root") .setJdbcPassword("123456") .setJdbcDriver("com.mysql.jdbc.Driver") .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); ProcessEngine processEngine = cfg.buildProcessEngine();
八、接着右键运行,生成数据库表信息。而后会在控制台输出很长的内容,等到输出中止,去数据库查看,会发现flowable数据库中新建了不少表,这样操做就能够继续了。
在运行实例的时候,关于数据库新建的这部分代码是不须要注释掉的(若数据库有更新的化会自动更新数据库内容)。git
九、接着书写一个关于请假的实例:
咱们须要再resource文件夹里新加配置文件 holiday-request.bpmn20.xml,内容是:github
<?xml version="1.0" encoding="UTF-8"?> <definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:flowable="http://flowable.org/bpmn" typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath" targetNamespace="http://www.flowable.org/processdef"> <process id="holidayRequest" name="Holiday Request" isExecutable="true"> <startEvent id="startEvent"/> <sequenceFlow sourceRef="startEvent" targetRef="approveTask"/> <userTask id="approveTask" name="Approve or reject request" flowable:candidateGroups="managers"/> <sequenceFlow sourceRef="approveTask" targetRef="decision"/> <exclusiveGateway id="decision"/> <sequenceFlow sourceRef="decision" targetRef="externalSystemCall"> <conditionExpression xsi:type="tFormalExpression"> <![CDATA[ ${approved} ]]> </conditionExpression> </sequenceFlow> <sequenceFlow sourceRef="decision" targetRef="sendRejectionMail"> <conditionExpression xsi:type="tFormalExpression"> <![CDATA[ ${!approved} ]]> </conditionExpression> </sequenceFlow> <serviceTask id="externalSystemCall" name="Enter holidays in external system" flowable:class="com.flowable.flowabledemo.CallExternalSystemDelegate"/> <sequenceFlow sourceRef="externalSystemCall" targetRef="holidayApprovedTask"/> <userTask id="holidayApprovedTask" name="Holiday approved" flowable:assignee="${employee}"/> <sequenceFlow sourceRef="holidayApprovedTask" targetRef="approveEnd"/> <serviceTask id="sendRejectionMail" name="Send out rejection email" flowable:class="com.flowable.flowabledemo.SendRejectionMail"/> <!--这里的class须要注意,后边跟的路径是你项目类问价所在的相对位置,若运行的时候报错,须要来修改这里的位置代码--> <sequenceFlow sourceRef="sendRejectionMail" targetRef="rejectEnd"/> <endEvent id="approveEnd"/> <endEvent id="rejectEnd"/> </process> </definitions>
十、接着在入口函数(main)下追加如下内容
/** * 部署工做流文件到流程引擎,其实就是将xml文件解析成Java对象,从而能够在程序里使用. */ RepositoryService repositoryService = processEngine.getRepositoryService(); Deployment deployment = repositoryService.createDeployment() .addClasspathResource("holiday-request.bpmn20.xml") .deploy(); /** * API使用 */ ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery() .deploymentId(deployment.getId()) .singleResult(); System.out.println("Found process definition : " + processDefinition.getName()); /** * 初始化流程变量 */ Scanner scanner= new Scanner(System.in); System.out.println("Who are you?"); String employee = scanner.nextLine(); System.out.println("How many holidays do you want to request?"); Integer nrOfHolidays = Integer.valueOf(scanner.nextLine()); System.out.println("Why do you need them?"); String description = scanner.nextLine(); /** * 经过RuntimeService启动一个流程实例,简称“启动流程”,这里就是启动请假流程 */ RuntimeService runtimeService = processEngine.getRuntimeService(); Map<String, Object> variables = new HashMap<String, Object>(); variables.put("employee", employee); variables.put("nrOfHolidays", nrOfHolidays); variables.put("description", description); ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("holidayRequest", variables); /** * 查询某个用户的任务 */ TaskService taskService = processEngine.getTaskService(); List<Task> tasks = taskService.createTaskQuery().taskCandidateGroup("managers").list(); System.out.println("You have " + tasks.size() + " tasks:"); for (int i=0; i<tasks.size(); i++) { System.out.println((i+1) + ") " + tasks.get(i).getName() + " created by [" + taskService.getVariables(tasks.get(i).getId()).get("employee") + "]"); } /** * 根据任务获取到这个任务涉及的流程变量 */ System.out.println("Which task would you like to complete?"); int taskIndex = Integer.valueOf(scanner.nextLine()); Task task = tasks.get(taskIndex - 1); Map<String, Object> processVariables = taskService.getVariables(task.getId()); System.out.println(processVariables.get("employee") + " wants " + processVariables.get("nrOfHolidays") + " of holidays. Do you approve this?"); /** * 若是是y,则流程结束 */ boolean approved = scanner.nextLine().toLowerCase().equals("y"); variables = new HashMap<String, Object>(); variables.put("approved", approved); taskService.complete(task.getId(), variables); /** * 查询历史数据,每一个步骤的花费的时间 */ HistoryService historyService = processEngine.getHistoryService(); List<HistoricActivityInstance> activities = historyService.createHistoricActivityInstanceQuery() .processInstanceId(processInstance.getId()) .finished() .orderByHistoricActivityInstanceEndTime().asc() .list(); for (HistoricActivityInstance activity : activities) { System.out.println(activity.getActivityId() + " took " + activity.getDurationInMillis() + " milliseconds"); }
十一、接着须要在主函数的同级目录下新建一个类文件 CallExternalSystemDelegate 内容是:
package com.flowable.flowabledemo; import org.flowable.engine.delegate.DelegateExecution; import org.flowable.engine.delegate.JavaDelegate; public class CallExternalSystemDelegate implements JavaDelegate { public void execute(DelegateExecution execution) { System.out.println("Calling the external system for employee " + execution.getVariable("employee")); } }
目录层级展现
1三、运行截图:
这时候是员工身份进行操做。 依次输入:姓名 请假时长 请假理由spring
1四、敲击回车,这时候会进入到管理者的角色,会让你选择处理哪个请假事务,显示的是有16个任务,向上滚动能够查看具体的内容的编号,咱们刚才新建的任务编号是14,因此这里输入14,敲击回车继续
1五、这时候会列出请假者的名字,请假时长,须要你输入y来赞成这个请假请求。
1六、而后敲击回车,程序完成,并输出相关信息。
因而,一个简单的flowable工做流实例就算是完成了!
点击下载源文件 点我 Touch Mesql