大家好,又见面了,我是你们的朋友全栈君。
最近有一段时间没写博客了,本来打算写写对于工作流的心得,但是工作时间比较饱和只好延后。最初接触工作流是上一家公司工作,具体我不透露哪家公司,只是感受到人情冷暖,或许公司都是这样,当你的价值被用完了也就是你走人的时候。好了,废话不多说,我们直接进入主题。
对于框架的选型,我推荐使用flowable框架,在最初的项目选型是选择activiti的,但是深入去了解框架的时候发现activiti还是有一些坑的,而flowable正是activiti框架的修正版,据了解flowable的背景是activiti原班人马开发出来的框架,而主导这个框架上更是得心应手,也修复了activiti的诸多bug。可能很多开发人员在框架选型上比较困扰,一方面出于对学习成本的考虑,一方面对框架性能、稳定性的考虑。在这里,我认为一个框架是否优秀的评判标准,不能取决于用的人多,而在于它的功能是否丰富,性能是否优越,后期扩展是否灵活等等,综合考虑下去选择。
考虑到读者会先了解一下flowable框架是否满足自身的项目需求,所以我会先入门讲解一下flowable框架的大致功能,后续再进行框架搭建。
对于flowable的了解也是来源于flowable的中文版手册,里面介绍得很详细,而我下面对一些常用的功能进行归纳总结。
比如,你实际的业务需求比较流程化,可能每一个步骤都需要有相关的人进行审批,直到最后结束,就像一条生产线一样,那么你就要考虑应用工作流框架了。举个例子:请假审批流程、财务审批流程、入职流程等等。
其实工作流框架在功能的应用上可能看不出来有什么明显的变化,但是对于内部代码上却可以很好的解耦,使得业务代码只需要关心当前的业务,而不需要进行流程的逻辑判断,一切交由工作流框架进行流转。除此之外,如果项目的流程化业务多那么接入工作流的好处就是可以将多个流程归结起来统一管理进行监控、性能分析等等。
举个例子:某业务上有三个步骤,每个步骤需要有相关人员进行审核,才能流转到下一步骤,每个步骤都有自己的业务逻辑。遇到上面的情况,第一种不整合工作流的做法就是三个步骤连在一起写,包括流转到下一步骤的判断,审核人员也需要根据在哪一步骤去判断获取相关人员,那么这种做法可行吗?可行,但是写起来代码臃肿,在代码上我们可以想办法把每个步骤抽离出来,但是如果步骤很多而且很多都是相同的逻辑,那这个代码看起来就不优雅了。有没有更加优雅的做法?有的,那就是使用工作流。
工作流的做法如下:
1. 流程画图,主要是通过可视化工具进行画图生成一个xml。
2. 流程部署,将流程图部署起来,写入到数据库中
3. 编写每个步骤的业务逻辑,如果多个步骤中的业务逻辑有相同的,则只写一个就可以了
4. 将写好的业务逻辑挂在在流程节点上
5. 启动项目,执行相关业务功能
对于上面两种做法,你可以理解为第一种做法有点类似于面向过程,就是事无大小都是自己亲力亲为去执行,第二种做法有点类似于面向对象,工作流充当指挥者,指挥着每个碎片化的业务逻辑,孰优孰略显而易见。
不难,建议多参考官方手册,后面会说说搭建的问题,还有一些需要注意的点。
首先你需要下载一个flowable的插件,画图也容易,都是组件式拖拽完成画图,然后在里面配置参数。
我先大体介绍一下flowable里面到底有哪些功能,后面再去详细地整合flowable框架,下面就先看看功能点欣赏一下就好~
Deployment deployment = repositoryService.createDeployment()
.name(process_name)
.addClasspathResource(resource_path)
.deploy();
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(process_name, map);
taskService.complete(taskId, map);
假设你现在的节点走错了想要退回去上一个节点,或者这个节点你想走到某一个节点,你可以调用一个跳转任意节点的方式实现。
runtimeService.createChangeActivityStateBuilder().processInstanceId(task.getProcessInstanceId()).moveActivityIdTo("approve1", "apply").changeState();
BpmnModel bpmnModel = repositoryService.getBpmnModel(pi.getProcessDefinitionId());
ProcessEngineConfiguration engconf = processEngine.getProcessEngineConfiguration();
ProcessDiagramGenerator diagramGenerator = engconf.getProcessDiagramGenerator();
InputStream in = diagramGenerator.generateDiagram(bpmnModel,"bmp", activityIds,flows,"宋体","宋体","宋体",null,1.0);
流程图部分代码片段,flowable框架自带的根据流程定义图生成的流程实例图,对当前正在进行的节点标红,可以很好的嵌入到前端给用户展示。
接上述待办列表提及到的角色绑定关系,这里来详细介绍如何做到查询待办可以只让当前操作人看到。
工作流的流程节点上是有用户和用户组的概念的,那么我们在流程画图的时候需要先提前指定该节点是由用户组操作还是由用户操作,这里的用户组其实说的就是“一群人“可以完成这个节点的操作,如何代表”一群人“,那么你需要有一个key值去映射多用户的关系。而在节点指定的是用户,那么就只有这个用户可以操作。
在实际的项目中,我们会有自己的一套<用户-角色-权限>体系,那么我们可以根据这套体系去对接工作流中的节点权限,所谓节点权限就是指这个节点处于当前操作的情况下有哪些用户可以去操作。
首先,如果你实际的项目中是有一套权限体系的,那么需要看你是根据权限来还是根据角色来,因为一个权限可以对应多个用户,一个角色也可以对应多个用户。本人当时是根据角色code去对接的,你可以理解为一个角色的一个唯一标识。 示例:
<userTask id="approve1" name="AP Settlement Leader" activiti:category="FINANCE-BOOKING-REPORT-AUDIT-1" xmlns:flowable="http://flowable.org/bpmn" flowable:candidateGroups="FINANCE-BOOKING-REPORT-AUDIT-1"></userTask>
<userTask id="apply" name="Settlement Operator" xmlns:flowable="http://flowable.org/bpmn" flowable:assignee="${user_account}"></userTask>
这里的“user_account”是一个流程变量的一个key,只要在调用流程发起的时候传入一个map映射一个用户名,那么流程在运行的时候就可以根据流程变量解析出用户,动态地将用户指定到节点上。当然,flowable:assignee这里也可以直接指定一个写死的用户名,那么这个节点就只有这个用户能够操作了
有几个地方需要注意,也是我自身亲身经历总结出来的:
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/143440.html原文链接:https://javaforall.cn