近期刚开始接触spring-activiti工作流,并运用于实际项目中,此处记录相关思想可做以后参考。

1. 统一服务执行入口,spring-activiti的ExecutionListener为多实例:

spring-activiti中写监听器,我们可以统一一个监听器入口,并准备springUtils可以实现获取spring的bean,将流程的执行逻辑转发到服务bean中执行。

package net.mshome.twisted.tmall.process;import lombok.extern.slf4j.Slf4j;
import net.mshome.twisted.tmall.util.SpringUtils;
import org.activiti.engine.ActivitiException;
import org.activiti.engine.delegate.DelegateExecution;
import org.activiti.engine.delegate.ExecutionListener;
import org.activiti.engine.delegate.Expression;
import org.apache.commons.lang3.StringUtils;@Slf4j
public class ProcessExecutionListener implements ExecutionListener {/*** 流程注入的流程配置的服务类,即spring的bean名*/private Expression servceName;/*** 流程注入的参数:推荐采用json格式传递参数*/private Expression param;/*** 传递的param参数*/private String paramString;/*** 具体的业务逻辑执行类,也是spring的bean*/private ProcessExecutionService processExecutionService;@Overridepublic void notify(DelegateExecution delegateExecution) {init();this.processExecutionService.execute(delegateExecution, paramString);}private void init() {if (servceName == null || StringUtils.isBlank(servceName.getExpressionText())) {throw new ActivitiException("serviceName is required");}String serviceName = servceName.getExpressionText();if (param == null || StringUtils.isBlank(param.getExpressionText())) {log.warn("{} executed without any param provided", serviceName);}this.paramString = param == null ? null : param.getExpressionText();Object service = SpringUtils.getApplicationContext().getBean(serviceName);if (service instanceof ProcessExecutionService) {processExecutionService = (ProcessExecutionService) service;} else {throw new ActivitiException(serviceName + " is not a implementation of " + ProcessExecutionService.class.getSimpleName());}}
}

2. 和spring bean关联的参数传递接口,流程服务service bean需实现此接口

package net.mshome.twisted.tmall.process;import org.activiti.engine.delegate.DelegateExecution;public interface ProcessExecutionService  {void execute(DelegateExecution delegateExecution, String param);}

3. 获取bean的类

package net.mshome.twisted.tmall.util;import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;@Component
public class SpringUtils implements ApplicationContextAware {private static ApplicationContext applicationContext;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {SpringUtils.applicationContext = applicationContext;}public static ApplicationContext getApplicationContext() {return applicationContext;}
}

4. 具体查询审批人服务

package net.mshome.twisted.tmall.process.service;import net.mshome.twisted.tmall.process.ProcessExecutionService;
import org.activiti.bpmn.model.FlowElement;
import org.activiti.bpmn.model.SequenceFlow;
import org.activiti.bpmn.model.UserTask;
import org.activiti.engine.delegate.DelegateExecution;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;import java.util.ArrayList;
import java.util.List;@Service
@Transactional
public class ProcessTaskAssignService implements ProcessExecutionService {@Overridepublic void execute(DelegateExecution delegateExecution, String param) {// 获取下一步节点,并判断是否是userTask类型FlowElement currentFlowElement = delegateExecution.getCurrentFlowElement();if (!(currentFlowElement instanceof SequenceFlow)) return;SequenceFlow sequenceFlow = (SequenceFlow) currentFlowElement;FlowElement targetNode = sequenceFlow.getTargetFlowElement();if (!(targetNode instanceof UserTask)) return;UserTask userTask = (UserTask) targetNode;// 实际情况需判断是否是会签节点,即多人审批节点boolean isMultiInstanceNode = userTask.getLoopCharacteristics() != null;// 获取配置的表达式String assignExpression = userTask.getAssignee();// fixme 去除el表达式的格式,设值,此处作为演示,没有去除delegateExecution.setVariable(assignExpression, "zhangsan"); // 实际情况可根据配置的人或者角色查询出用户,然后设值// 获取配置的表达式String assigneeListExpression = userTask.getLoopCharacteristics().getInputDataItem();List<String> userList = new ArrayList<>();// fixme 去除el表达式的格式,设值,此处作为演示,没有去除delegateExecution.setVariable(assigneeListExpression, userList);}
}

5.  动态指定下一步的审批人,可以在连接到userTask类型的节点线上也就是sequeceFlow上增加执行服务,取线上约定固定格式的审批人表达式如 assigneeList,设置参数。如 { "userList" : [], "roleList":[] } ,如需要根据业务查询审批人,自行写服务。

番外篇:

1. 流程开始时,可写服务将流程相关参数和流程状态更新进业务表,还可以将流程需要的业务参数放入,比如整个表单对象放入流程。以达到可配置el表达式决定流程的走向效果或者其他作用。

2. 流程执行时可配置服务类,将下一步的节点名写入业务表,如下一步是分支,则可在前一步,传入参数param当作下一步的节点名。

spring-activiti动态指定审批人及其设计思想相关推荐

  1. 类钉钉,activiti5.22发起流程时候动态指定审批人

    完整项目 一个简单的申请流程如下: <?xml version="1.0" encoding="UTF-8"?> <definitions x ...

  2. 基于Spring框架的Wap门户网站设计思想(转)

    在Wap手机门户网站的程序设计过程中,我们使用了Spring 框架结构.在前台的jsp页面中,重点应用了web MVC设计思想和Spring 对JDBC的封装策略.MVC即Model –View-Co ...

  3. Spring 框架蕴含的设计思想

    在 Google Guava 源码讲解中,我们讲到开发通用功能模块的一些比较普适的开发思想,比如产品意识.服务意识.代码质量意识.不要重复早轮子等.今天,我们剖析一下 Spring 框架背后的一些经典 ...

  4. Spring核心和设计思想

    文章目录 1.Spring是什么? 什么是容器? 什么是IoC呢? 控制反转程序开发 理解Spring IoC DI概念 Spring的创建和使用 创建Spring项目 添加Spring框架支持 创建 ...

  5. 【手写系列】透彻理解Spring事务设计思想之手写实现

    事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败.事务具有4个特性:Atomicity(原子性),Consistency(一致性),Isolation(隔离性),Dura ...

  6. 从面向对象设计思想出发理解Spring AOP编程

    都说AOP是OOP(面向对象)的继承与延续,我觉得理解AOP还是得从OOP出发,经历从暴露问题到解决问题的过程. 目录 一. 面向对象设计思想(OOP) (1)概述 1. POP编程 2. OOP的优 ...

  7. 《Spring设计思想》AOP设计基本原理

    0.前言 Spring 提供了AOP(Aspect Oriented Programming) 的支持, 那么,什么是AOP呢?本文将通过一个另外一个角度来诠释AOP的概念,帮助你更好地理解和使用Sp ...

  8. 透彻理解Spring事务设计思想之手写实现

    2019独角兽企业重金招聘Python工程师标准>>> 前言 事务,是描述一组操作的抽象,比如对数据库的一组操作,要么全部成功,要么全部失败.事务具有4个特性:Atomicity(原 ...

  9. 电子计算机工作原理及设计思想为什么理论,动态偏振控制器的工作原理、系统设计及应用...

    1 引 言 偏振是量子光的一个重要和常用的性质.因此,在量子安全通信系统中,经常通过改变偏振态来进行编解码,而动态偏振控制器(DPC)作为一种改变输入光偏振态的光器件,直接参与传输数据的编解码,在量子 ...

最新文章

  1. the fair-sounding
  2. 解决Ubuntu16.04重启进入initramfs
  3. 使用TMG2010企业版组建大型***网络之3-配置NLB
  4. HttpCLient工具使用讲解
  5. 【分布式】Zookeeper的服务器角色
  6. Paragon NTFS提示安装分卷失败,怎么解决
  7. c# 标准正太分布函数_数据处理中0-1规范化和标准化
  8. C#winform之自定义按钮形状(初级版)
  9. mysql 临时表权限_MySQL临时表浅析
  10. iOS iPhone X底部设置高度 白色底部显示
  11. 用 SpriteKit 做一个逃逸游戏 (2)
  12. matlab留学生作业代做,代写Canvas留学生作业、MatLab编程语言作业调试、MatLab实验作业代做、代写program课程作业...
  13. 朱令被投毒案关键人物语料分析之孙维篇
  14. Android P Asan使用总结
  15. unity摄像头实物识别_MAD Gaze推出人脸识别AR智能眼镜+AI安防方案赋能智慧城市...
  16. 数字人民币来了!它与支付宝、微信有什么区别吗?
  17. 磨金石教育摄影技能干货分享|优秀摄影作品欣赏——世界掠影
  18. 一行代码解决IE浏览器的兼容问题
  19. python——pandas——dropna()函数
  20. transform.invert 预处理逆操作

热门文章

  1. 愛上一座城是因为爱上一个人
  2. 探索无限可能:物联网技术的未来应用引领智能化时代
  3. 回首阿里十年开发生涯,我花了几个月时间整理了这份Java笔记
  4. My Python CookBook
  5. 三星android p公测,三星独占时间到,Android平台《堡垒之夜》开放公测
  6. java tcp client 断开_HttpClient出现TCP连接异常关闭发送RST包
  7. 如何通过API接口获取北京交通流量数据?
  8. 行业语录·202012
  9. eda技术试卷_《EDA技术》期末试卷(A)参考答案与评分标准.doc
  10. jpanel添加html,jpanel是什么?