【整合篇】Activiti业务与流程的整合
对于不管是Activtit还是jbpm来说,业务与流程的整合均类似。启动流程是绑定业务。流程与业务的整合放到动态代理中
- /**
- * 启动改动课程流程Leave leave,
- *
- * @param leave
- */
- @RequestMapping(value = "start", method = RequestMethod.POST)
- public String startWorkflow(Leave leave,RedirectAttributes redirectAttributes, HttpSession session) {
- try {
- User user = UserUtil.getUserFromSession(session);
- // 用户未登录不能操作,实际应用使用权限框架实现,比如Spring Security、Shiro等
- if (user == null || StringUtils.isBlank(user.getId())) {
- return "redirect:/login?timeout=true";
- }
- leave.setUserId(user.getId());
- Map<String, Object> variables = new HashMap<String, Object>();
- variables.put("leave", leave);
- //保存业务实体
- leave.setTestId(new Date().toString());
- leaveBean.saveBeforeEntity(leave);
- Leave Leavetest=null;
- Leavetest=leaveBean.queryByTestid(leave.getTestId());
- leave=Leavetest;
- logger.debug("save entity: {}", leave);
- //不再获取id,改为获取类 .getClass().getSimpleName().toString();
- //String businessKey = "leave";
- String businessKey = leave.getId().toString();
- ProcessInstance processInstance = null;
- /*加入的代码--begin--Proxy*/
- // 调用业务,保存申请信息
- startNode.common(businessKey, variables,runtimeService,identityService);
- LogHandler1 logHandler = startNode.new LogHandler1();
- //放到代理中设置值了
- //stuCourseApply.setExecuteId(pi.getId());
- LeaveBean leaveBeanProxy=(LeaveBean)logHandler.newProxyInstanceStart(leaveBean);
- leaveBeanProxy.updeatChangeApply(leave);
- /*加入的代码--end--Proxy*/
- /*放到代理中--begin--Proxy*/
- /* try {
- // 用来设置启动流程的人员ID,引擎会自己主动把用户ID保存到activiti:initiator中
- identityService.setAuthenticatedUserId(leave.getUserId());
- processInstance = runtimeService.startProcessInstanceByKey("easyChangeCourse", businessKey, variables);
- String processInstanceId = processInstance.getId();
- leave.setProcessInstanceId(processInstanceId);
- logger.debug("start process of {key={}, bkey={}, pid={}, variables={}}", new Object[]{"easyChangeCourse", processInstanceId, variables});
- } finally {
- identityService.setAuthenticatedUserId(null);
- }*/
- /*放到代理中--end--Proxy*/
- //+ processInstance.getId()
- redirectAttributes.addFlashAttribute("message", "流程已启动" );
- } catch (ActivitiException e) {
- if (e.getMessage().indexOf("no processes deployed with key") != -1) {
- logger.warn("没有部署流程!", e);
- redirectAttributes.addFlashAttribute("error", "没有部署流程,请在[工作流]->[流程管理]页面点击<又一次部署流程>");
- } else {
- logger.error("启动请假流程失败:", e);
- redirectAttributes.addFlashAttribute("error", "系统内部错误!
");
- }
- } catch (Exception e) {
- logger.error("启动请假流程失败:", e);
- redirectAttributes.addFlashAttribute("error", "系统内部错误!
");
- }
- return "redirect:/oa/leave/apply";
- }
动态代理:
- package com.tgb.itoo.activiti.controller;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import java.util.Map;
- import org.activiti.engine.IdentityService;
- import org.activiti.engine.RuntimeService;
- import org.activiti.engine.runtime.ProcessInstance;
- import org.slf4j.Logger;
- import org.slf4j.LoggerFactory;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.stereotype.Component;
- import org.springframework.transaction.annotation.Transactional;
- import com.tgb.itoo.basic.entity.Leave;
- @Component
- @Transactional
- public class StartNode{
- private Logger logger = LoggerFactory.getLogger(getClass());
- //定义一个属性变量
- private Map<String, Object> variables;
- private String businessKey;
- //设置人人员
- protected IdentityService identityService;
- @Autowired
- public void setIdentifyService(IdentityService identityService) {
- this.identityService = identityService;
- }
- protected RuntimeService runtimeService;
- @Autowired
- public void setRuntimeService(RuntimeService runtimeService) {
- this.runtimeService = runtimeService;
- }
- @Autowired
- RuntimeService runtimeService1;
- public void common(String businessKey,Map<String, Object> variables,RuntimeService runtimeService,IdentityService identityService){
- this.variables=variables;
- this.businessKey=businessKey;
- this.runtimeService=runtimeService;
- this.identityService=identityService;
- }
- //想尝试是否能依据其它方式传參。new的话太耗费资源
- /*public StartAbstractJBPM(String pdKey,Map<String, Object> variablesMap,JBPMService jbpmService){
- this.variablesMap=variablesMap;
- this.pdKey=pdKey;
- this.jbpmService=jbpmService;
- }*/
- //动态代理类仅仅能代理接口(不支持抽象类),代理类都须要实现InvocationHandler类,实现invoke方法。
该invoke方法就是调用被代理接口的全部方法时须要调用的,该invoke方法返回的值是被代理接口的一个实现类
- public class LogHandler1 implements InvocationHandler{
- // 目标对象
- private Object targetObject;
- //绑定关系,也就是关联到哪个接口(与详细的实现类绑定)的哪些方法将被调用时,运行invoke方法。
- public Object newProxyInstanceStart(Object targetObject){
- this.targetObject=targetObject;
- //该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
- //第一个參数指定产生代理对象的类载入器,须要将其指定为和目标对象同一个类载入器
- //第二个參数要实现和目标对象一样的接口,所以仅仅须要拿到目标对象的实现接口
- //第三个參数表明这些被拦截的方法在被拦截时须要运行哪个InvocationHandler的invoke方法
- //依据传入的目标返回一个代理对象
- return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
- targetObject.getClass().getInterfaces(),this);
- }
- @Override
- //关联的这个实现类的方法被调用时将被运行
- // InvocationHandler接口的方法。proxy表示代理,method表示原对象被调用的方法,args表示方法的參数
- public Object invoke(Object proxy, Method method, Object[] args)
- throws Throwable {
- System.out.println("start-->>");
- for(int i=0;i<args.length;i++){
- System.out.println(args[i]);
- }
- Object ret=null;
- try{
- //原对象方法调用前处理日志信息
- System.out.println("satrt-->>");
- //启动流程
- //调用目标方法
- Leave leave=(Leave)args[0];
- // 用来设置启动流程的人员ID,引擎会自己主动把用户ID保存到activiti:initiator中
- try {
- identityService.setAuthenticatedUserId(leave.getUserId());
- ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ChangeCourse", businessKey, variables);
- String processInstanceId = processInstance.getId();
- leave.setProcessInstanceId(processInstanceId);
- logger.debug("start process of {key={}, bkey={}, pid={}, variables={}}", new Object[]{"ChangeCourse", processInstanceId, variables});
- } finally {
- identityService.setAuthenticatedUserId(null);
- }
- args[0]=leave;
- ret=method.invoke(targetObject, args);
- //调用完毕当前结点
- // >> 办理完第1个任务“提交申请”
- //jbpmService.completeFirstTask(pi);
- //原对象方法调用后处理日志信息
- System.out.println("success-->>");
- }catch(Exception e){
- e.printStackTrace();
- System.out.println("error-->>");
- throw e;
- }
- return ret;
- }
- }
- }
- /**
- * 任务列表ERROR [stderr] (http-localhost/127.0.0.1:8080-3) ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider com.sun.script.javascript.RhinoScriptEngineFactory not found
- *
- * @param leave
- */
- @RequestMapping(value = "list/task")
- public ModelAndView taskList(HttpSession session, HttpServletRequest request) {
- List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
- String userId = UserUtil.getUserFromSession(session).getId();
- results=abstractTaskList(userId);
- return new ModelAndView("/oa/leave/taskList","results",results);
- }
- /**
- * 抽象出来的查看任务列表。与基本业务无关
- *
- * @param userId 用户id
- * @return
- */
- public List<Map<String, Object>> abstractTaskList(String userId){
- List<Leave> results = new ArrayList<Leave>();
- // 依据当前人的ID查询
- TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);
- List<Task> tasks = taskQuery.list();
- int i=0;
- List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
- // 依据流程的业务ID查询实体并关联
- for (Task task : tasks) {
- String processInstanceId = task.getProcessInstanceId();
- ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();
- String businessKey = processInstance.getBusinessKey();
- if (businessKey == null) {
- continue;
- }
- Map<String, Object> map = new HashMap<String, Object>();
- Leave leave = leaveBean.findEntityById(businessKey);
- //leave.setProcessInstance(processInstance);
- //leave.setProcessDefinition(getProcessDefinition(processInstance.getProcessDefinitionId()));
- //leave.setTask(task);
- map.put("leave", leave);//存入“申请信息”
- map.put("task", task);
- map.put("processDefinition", getProcessDefinition(processInstance.getProcessDefinitionId()));
- map.put("processInstance", processInstance);//存入“流程实例”
- mapList.add(map);
- /*Leave leave=updateEntity(processInstance,task,businessKey);
- results.add(leave); */
- i=i+1;
- }
- return mapList;
- }
- /**
- * 读取执行中的流程实例(查看我的申请)involvedUser(userId)(涉及到的用户)
- *
- * @return
- */
- @RequestMapping(value = "list/running")
- public ModelAndView runningList(HttpSession session,HttpServletRequest request) {
- String userId = UserUtil.getUserFromSession(session).getId();
- List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
- results=abstractRuningList(userId);
- return new ModelAndView ("/oa/leave/running","results",results);
- }
- /**
- * 抽象出来读取执行中的流程实例(查看我的申请)。与基本业务无关
- *
- * @param userId 用户id
- * @return
- */
- public List<Map<String, Object>> abstractRuningList(String userId){
- List<Leave> results = new ArrayList<Leave>();
- ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery().processDefinitionKey("ChangeCourse").involvedUser(userId).active().orderByProcessInstanceId().desc();//依据流程定义Key查询流程实例
- List<ProcessInstance> list = query.list();
- List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
- // 关联业务实体
- for (ProcessInstance processInstance : list) {
- String businessKey = processInstance.getBusinessKey();
- if (businessKey == null) {
- continue;
- }
- // 设置当前任务信息
- List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).active().orderByTaskCreateTime().desc().listPage(0, 1);
- Map<String, Object> map = new HashMap<String, Object>();
- Leave leave = leaveBean.findEntityById(businessKey);
- /*leave.setProcessInstance(processInstance);
- leave.setProcessDefinition(getProcessDefinition(processInstance.getProcessDefinitionId()));
- leave.setTask(tasks.get(0));*/
- map.put("leave", leave);//存入“考试信息”
- map.put("task", tasks.get(0));
- map.put("processDefinition", getProcessDefinition(processInstance.getProcessDefinitionId()));
- map.put("processInstance", processInstance);//存入“流程实例”
- mapList.add(map);
- /*Leave leave=updateEntity(processInstance,task,businessKey);
- results.add(leave); */
- //Leave leave=updateEntity(processInstance,tasks.get(0),businessKey);
- }
- return mapList;
- }
- /**
- * 读取完毕的流程实例(已经完毕的流程申请-我)
- *
- * @return
- */
- @RequestMapping(value = "list/finished")
- public ModelAndView finishedList(HttpSession session,HttpServletRequest request) {
- String userId = UserUtil.getUserFromSession(session).getId();
- List<Leave> results = new ArrayList<Leave>();
- HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().processDefinitionKey("ChangeCourse").involvedUser(userId).finished().orderByProcessInstanceEndTime().desc();
- List<HistoricProcessInstance> list = query.list();
- List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();
- // 关联业务实体
- for (HistoricProcessInstance historicProcessInstance : list) {
- Map<String, Object> map = new HashMap<String, Object>();
- String businessKey = historicProcessInstance.getBusinessKey();
- Leave leave = leaveBean.findEntityById(businessKey);
- /* leave.setProcessDefinition(getProcessDefinition(historicProcessInstance.getProcessDefinitionId()));
- leave.setHistoricProcessInstance(historicProcessInstance);
- results.add(leave);*/
- map.put("leave", leave);//存入“申请信息”
- map.put("processDefinition", getProcessDefinition(historicProcessInstance.getProcessDefinitionId()));
- map.put("historicProcessInstance", historicProcessInstance);//存入“流程实例”
- mapList.add(map);
- }
- return new ModelAndView("/oa/leave/finished","results",mapList);
- }
- /**
- * 完毕任务
- *
- * @param id
- * @return
- */
- @RequestMapping(value = "/complete/{id}", method = {RequestMethod.POST, RequestMethod.GET})
- @ResponseBody
- public String complete(@PathVariable("id") String taskId, Variable var) {
- try {
- //deptLeaderPass=true or hrBackReason=666, hrPass=false-----{leaderBackReason=78, deptLeaderPass=false}
- Map<String, Object> variables = var.getVariableMap();
- //taskService.getVariables(taskId);
- //Object variablesResult=variables.get("deptLeaderPass");
- //variablesResult=variables.get("hrPass");
- taskService.complete(taskId, variables);
- //获取map中的值
- // if(hrPass=true){
- // //更新业务表信息
- // }
- return "success";
- } catch (Exception e) {
- logger.error("error on complete task {}", new Object[]{taskId, e});
- return "error";
- }
- }
总结:
对于在流程与业务的整合中应用动态代理也不知道是否符合AOP的理念,类似其它方面的流程操作还未抽取出来(交互太多),在这里记录一下学习Activiti的一个过程,在之后的尝试中能够换个方式。换个思路,直接将整个工作流应用抽取出来(请假,改动课程等)。
【整合篇】Activiti业务与流程的整合的更多相关文章
- activiti自己定义流程之整合(四):整合自己定义表单部署流程定义
综合前几篇博文内容.我想在整合这一部分中应该会有非常多模块会跳过不讲,就如自己定义表单的表单列表那一块,由于这些模块在整合的过程中都差点儿没有什么修改,再多讲也是反复无用功. 正由于如此,在创建了流程 ...
- activiti自己定义流程之整合(二):使用angular js整合ueditor创建表单
基础环境搭建完成,接下来就该正式着手代码编写了,在说代码之前.我认为有必要先说明一下activit自己定义流程的操作. 抛开自己定义的表单不谈.通过之前的了解,我们知道一个新的流程開始.是在启动流程实 ...
- activiti自己定义流程之整合(三):整合自己定义表单创建模型
本来在创建了表单之后应该是表单列表和预览功能.可是我看了看整合的代码,和之前没实用angularjs的基本没有什么变化,一些极小的变动也仅仅是基于angularjs的语法,因此全然能够參考之前说些的表 ...
- activiti自己定义流程之整合(五):启动流程时获取自己定义表单
流程定义部署之后,自然就是流程定义列表了,但和前一节一样的是,这里也是和之前单独的activiti没什么差别.因此也不多说.我们先看看列表页面以及相应的代码,然后在一步步说明点击启动button时怎样 ...
- activiti自定义流程之整合(四):整合自定义表单部署流程定义
综合前几篇博文内容,我想在整合这一部分中应该会有很多模块会跳过不讲,就如自定义表单的表单列表那一块,因为这些模块在整合的过程中都几乎没有什么改动,再多讲也是重复无用功. 正因为如此,在创建了流程模型之 ...
- activiti自定义流程之Spring整合activiti-modeler5.16实例(六):启动流程
注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建 (2)创建流程模型:activiti自定义流程之Spring ...
- activiti自定义流程之Spring整合activiti-modeler5.16实例(五):流程定义列表
注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建 (2)创建流程模型:activiti自定义流程之Spring ...
- activiti自定义流程之Spring整合activiti-modeler5.16实例(四):部署流程定义
注:(1)环境搭建:activiti自定义流程之Spring整合activiti-modeler5.16实例(一):环境搭建 (2)创建流程模型:activiti自定义流程之Spring ...
- activiti自定义流程之整合(二):使用angular js整合ueditor创建表单
注:整体环境搭建:activiti自定义流程之整合(一):整体环境配置 基础环境搭建完毕,接下来就该正式着手代码编写了,在说代码之前,我觉得有必要先说明一下activit自定义流程的操作. 抛开自定义 ...
随机推荐
- css3 选择器 权重问题 (第一部分)
其实我现在写的这些博文笔记都是我很早之前学习的时候所写的笔记,只不过之前是没有写博客的习惯,所以都是写在word文档中个人需要的时候看而已.最近刚刚开了博客,所以想将自己的笔记贴到博客. 但是现在看来 ...
- go的常量与变量
一.常量 1.1 定义 常量使用关键字const 定义,用于存储不会变化的数据 定义方法 const identifier [type] = value package main // 常量定义 co ...
- 树形$dp$学习笔记
今天学习了树形\(dp\),一开始浏览各大\(blog\),发现都\(TM\)是题,连个入门的\(blog\)都没有,体验极差.所以我立志要写一篇可以让初学树形\(dp\)的童鞋快速入门. 树形\(d ...
- SQLServer2008 关于数值字段列的累计
create table #temp20110610( id int identity(1,1), date varchar(8), qty float) insert int ...
- Unity引擎GUI之Canvas和EventSystem
最近想写一套关于UGUI所有控件的基础使用教程系列,主要是根据本人的使用心得以及部分测试附带字面翻译来写的,所以其中可能难以避免会有不正确的地方. 好了进入主题,既然是第一篇,我觉得我有必要先介绍一下 ...
- SSIS 无法在 unicode 和非 unicode 字符串数据类型之间转换
最近在学SSIS,遇到一个问题,把平面文件源的数据导入到EXCEL中. 平面文件源的对象是CSV,读进来的PhoneNumber是 DT_STR 然后倒入Excel 对应列建立的是longtext 一 ...
- 【Oracle】OGG(Oracle GoldenGate)简介及搭建过程
GoldenGate公司简介 GoldenGate公司专注于数据同步领域,是实现数据同步技术的领导者.至2007年,在全球35个国家售出超过2000个许可证,客户分布在政府.银行.电信.证券.传媒.医 ...
- C#关闭退出线程的几种方法
.Application.Exit(); //强制所有消息中止,退出所有的窗体,但是若有托管线程(非主线程),也无法干净地退出: .System.Environment.Exit(); //无论在主线 ...
- dubbo之泛化实现
实现泛化调用 泛化接口调用方式主要用于客户端没有 API 接口及模型类元的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过 Gene ...
- dubbo之静态服务
有时候希望人工管理服务提供者的上线和下线,此时需将注册中心标识为非动态管理模式 <dubbo:registry address="10.20.141.150:9090" dy ...
