标签:
对于无论是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的一个过程,在之后的尝试中可以换个方式,换个思路,直接将整个工作流应用抽取出来(请假,修改课程等)。
标签:
原文地址:http://blog.csdn.net/hejingyuan6/article/details/43850413