【整合篇】Activiti业务与流程的整合

来源:互联网 发布:转帖软件 编辑:程序博客网 时间:2024/05/22 01:58

    继上篇博客:【整合篇】JBPM4.4业务与流程的整合

    对于无论是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@Transactionalpublic 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的一个过程,在之后的尝试中可以换个方式,换个思路,直接将整个工作流应用抽取出来(请假,修改课程等)。



3 1
原创粉丝点击