个人项目中第一次使用工作流,发现遇到了不少问题,谈谈个人的使用心得,欢迎吐槽:
使用的技术:springboot(2.0.1) + activiti (5.22) 当时没有选择更高版本的,是因为这个版本的参考资源比较多;
- 部署activiti环境
- 引入jar包
- 配置: 我的配置如下:(项目启动自动生成工作流的表)
-
spring.datasource.url=jdbc:mysql:// spring.datasource.username= spring.datasource.password=
#自动检查、部署流程定义文件 spring.activiti.check-process-definitions=false #自动更新数据库结构 spring.activiti.database-schema-update=true #流程定义文件存放目录 spring.activiti.process-definition-location-prefix=classpath:/processes/
/** * 引入工作流配置类 */ @Configuration public class ActivitiConfig extends AbstractProcessEngineAutoConfiguration { @Bean(name = "activitiDataSource") @Primary @ConfigurationProperties(prefix = "spring.datasource") //指向统一的数据库,也可以单独为工作流配置一个数据库 public DataSource activitiDataSource() { return new DruidDataSource(); } @Bean public PlatformTransactionManager transactionManager() { return new DataSourceTransactionManager(activitiDataSource()); } @Bean public SpringProcessEngineConfiguration springProcessEngineConfiguration() { SpringProcessEngineConfiguration configuration = new SpringProcessEngineConfiguration(); configuration.setDataSource(activitiDataSource()) .setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE) .setJobExecutorActivate(true); configuration.setTransactionManager(transactionManager()); configuration.setLabelFontName("宋体"); configuration.setActivityFontName("宋体"); configuration.setAnnotationFontName("宋体"); return configuration; } }
- 流程定义
- 通俗的说就是创建流程图
- 已这样一个为例
- 员工提交申请单才启动流程
- 向activiti中部署流程定义
- 使用测试类进行流程部署;
- 我个人偏向使用接口进行部署(原理一样)
- 项目正式上线可以注释3中的代码
- 启动一个流程实例
- 何为启动一个流程实例:
- A创建了一个采购单,启动了一个流程实例;B也创建了一个采购单,也启动了一个流程实例
- 查询待办任务
- 查询自己名下的待办任务,由activiti自动化管理了
- 办理任务
- 任务办理后流程执行到哪一步由activiti自动管理
- 流程结束
流程图配置说明:
比如我们要配置人员来审批创建的采购单:
在1中配置: 固定分配 可以配置人员名称,userId都可以;之后就可以根据人员名称,userId查到当前人员的待办任务进行审核了
缺点:在流程中配置固定的,审批人员的修改,需要修改流程配置文件,扩展性差,不建议这样使用
在1中配置变量:使用UEL表达式 ${userId} userId是流程变量名称
${userId}获取流程变量的值 ,作为任务的办理人
这样使用的话,我们就必须在流程启动的时候,设置这个流程变量的值
ProcessInstance startProcessInstanceById(String processDefinitionId, String businessKey, Map<String, Object> variables);解释说明: RuntimeService的启动流程实例的方法,根据自己的业务进行选择
processDefinitionId : 必填字段,流程定义的id名称:
businessKey: 流程运行只的业务id,比如当前业务我们可以使用申请单id,作为业务id,在其他的流程节点可以获取,进行查询具体的业务数据,此字段为非必填字段
variables: 非必填字段,如果我们使用固定配置,则不需要使用,如果使用动态名称配置可以使用;
如: 我们在启动流程的时候,如果部门有多个人员用审批权限,我们可以手动指定人员进行审批
Map<String, Object> variables = new HashMap<>();
variables.put("userId","123456");
123456 是部门经理的id
之后部门经理根据自己的用户id就能查到自己的代办任务
使用2配置: 算是另一种半固定配置,可以配置成方法获取待办人员
${userService.getDeptManagerId(execution)}
这样配置,需要我们在userService中添加这个方法获取部门主任的id,返回值可以是list,可以是String
优点: 不算完全的固定匹配,至少部门经理换了不需要修改代码,不需要手动指定审批人员
缺点:需要配置,当前部门的经理,
可以硬编码A部门,获取部门经理;
查询提交当前流程需要处理的部门经理(这个地方结合自己的业务使用的好也是一种优点)
使用3的配置:
对人员进行分组,A审批组,B审批组,需要用户模块进行配置;
工作流中有用户,分组表,不过一般会用自己的用户表,可以做数据同步或
扩展性较好:本人项目中没有使用这个,觉得应该各方式1的配置差不多,有兴趣可以自己尝试
工作流开发原则:
-
业务流程的管理由activiti负责,业务功能由业务系统负责
-
activiti和业务系统整合时,数据共享 问题,让activiti找到业务系统数据(通过businessKey),让业务系统找到activiti的数据(在业务系统表中添加流程实例的id)。
-
需要自定义对象将activiti和业务系统控制层进行隔离