zoukankan      html  css  js  c++  java
  • 【整合篇】Activiti业务与流程的整合

    对于不管是Activtit还是jbpm来说,业务与流程的整合均类似。启动流程是绑定业务。流程与业务的整合放到动态代理中

    [java] view plain copy
     print?

    在CODE上查看代码片派生到我的代码片

    1. /** 
    2.      * 启动改动课程流程Leave leave,  
    3.      * 
    4.      * @param leave 
    5.      */  
    6.     @RequestMapping(value = "start", method = RequestMethod.POST)  
    7.     public String startWorkflow(Leave leave,RedirectAttributes redirectAttributes, HttpSession session) {  
    8.         try {  
    9.               
    10.             User user = UserUtil.getUserFromSession(session);  
    11.             // 用户未登录不能操作,实际应用使用权限框架实现,比如Spring Security、Shiro等  
    12.             if (user == null || StringUtils.isBlank(user.getId())) {  
    13.                 return "redirect:/login?timeout=true";  
    14.             }              
    15.             leave.setUserId(user.getId());  
    16.             Map<String, Object> variables = new HashMap<String, Object>();   
    17.             variables.put("leave", leave);  
    18.             //保存业务实体  
    19.             leave.setTestId(new Date().toString());              
    20.             leaveBean.saveBeforeEntity(leave);   
    21.               
    22.             Leave Leavetest=null;  
    23.             Leavetest=leaveBean.queryByTestid(leave.getTestId());  
    24.             leave=Leavetest;  
    25.             logger.debug("save entity: {}", leave);   
    26.               
    27.               
    28.             //不再获取id,改为获取类  .getClass().getSimpleName().toString();            
    29.             //String businessKey = "leave";              
    30.             String businessKey = leave.getId().toString();              
    31.             ProcessInstance processInstance = null;  
    32.               
    33.            /*加入的代码--begin--Proxy*/  
    34.               
    35.             // 调用业务,保存申请信息        
    36.             startNode.common(businessKey, variables,runtimeService,identityService);  
    37.             LogHandler1 logHandler = startNode.new LogHandler1();  
    38.             //放到代理中设置值了  
    39.             //stuCourseApply.setExecuteId(pi.getId());  
    40.               
    41.             LeaveBean leaveBeanProxy=(LeaveBean)logHandler.newProxyInstanceStart(leaveBean);    
    42.             leaveBeanProxy.updeatChangeApply(leave);      
    43.               
    44.         /*加入的代码--end--Proxy*/  
    45.            
    46.               
    47.         /*放到代理中--begin--Proxy*/   
    48.            /* try { 
    49.                 // 用来设置启动流程的人员ID,引擎会自己主动把用户ID保存到activiti:initiator中 
    50.                 identityService.setAuthenticatedUserId(leave.getUserId());                                 
    51.                 processInstance = runtimeService.startProcessInstanceByKey("easyChangeCourse", businessKey, variables); 
    52.                 String processInstanceId = processInstance.getId(); 
    53.                 leave.setProcessInstanceId(processInstanceId); 
    54.                 logger.debug("start process of {key={}, bkey={}, pid={}, variables={}}", new Object[]{"easyChangeCourse", processInstanceId, variables}); 
    55.             } finally { 
    56.                 identityService.setAuthenticatedUserId(null); 
    57.             }*/  
    58.         /*放到代理中--end--Proxy*/       
    59.               
    60.         //+ processInstance.getId()  
    61.             redirectAttributes.addFlashAttribute("message""流程已启动" );  
    62.         } catch (ActivitiException e) {  
    63.             if (e.getMessage().indexOf("no processes deployed with key") != -1) {  
    64.                 logger.warn("没有部署流程!", e);  
    65.                 redirectAttributes.addFlashAttribute("error""没有部署流程,请在[工作流]->[流程管理]页面点击<又一次部署流程>");  
    66.             } else {  
    67.                 logger.error("启动请假流程失败:", e);  
    68.                 redirectAttributes.addFlashAttribute("error""系统内部错误!

      ");  

    69.             }  
    70.         } catch (Exception e) {  
    71.             logger.error("启动请假流程失败:", e);  
    72.             redirectAttributes.addFlashAttribute("error""系统内部错误!

      ");  

    73.         }  
    74.         return "redirect:/oa/leave/apply";  
    75.     }  

    动态代理:


    [java] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. package com.tgb.itoo.activiti.controller;  
    2.   
    3. import java.lang.reflect.InvocationHandler;  
    4. import java.lang.reflect.Method;  
    5. import java.lang.reflect.Proxy;  
    6. import java.util.Map;  
    7.   
    8. import org.activiti.engine.IdentityService;  
    9. import org.activiti.engine.RuntimeService;  
    10. import org.activiti.engine.runtime.ProcessInstance;  
    11. import org.slf4j.Logger;  
    12. import org.slf4j.LoggerFactory;  
    13. import org.springframework.beans.factory.annotation.Autowired;  
    14. import org.springframework.stereotype.Component;  
    15. import org.springframework.transaction.annotation.Transactional;  
    16. import com.tgb.itoo.basic.entity.Leave;  
    17.   
    18. @Component  
    19. @Transactional  
    20. public class StartNode{  
    21.   
    22.     private Logger logger = LoggerFactory.getLogger(getClass());  
    23.     //定义一个属性变量  
    24.     private Map<String, Object> variables;  
    25.     private String businessKey;  
    26.       
    27.     //设置人人员  
    28.     protected IdentityService identityService;  
    29.     @Autowired  
    30.     public void setIdentifyService(IdentityService identityService) {  
    31.         this.identityService = identityService;  
    32.     }  
    33.     protected RuntimeService runtimeService;  
    34.     @Autowired  
    35.     public void setRuntimeService(RuntimeService runtimeService) {  
    36.         this.runtimeService = runtimeService;  
    37.     }  
    38.       
    39.     @Autowired  
    40.     RuntimeService runtimeService1;  
    41.       
    42.     public void common(String businessKey,Map<String, Object> variables,RuntimeService runtimeService,IdentityService identityService){  
    43.         this.variables=variables;  
    44.         this.businessKey=businessKey;  
    45.         this.runtimeService=runtimeService;  
    46.         this.identityService=identityService;  
    47.     }  
    48.     //想尝试是否能依据其它方式传參。new的话太耗费资源  
    49.     /*public StartAbstractJBPM(String pdKey,Map<String, Object> variablesMap,JBPMService jbpmService){ 
    50.         this.variablesMap=variablesMap; 
    51.         this.pdKey=pdKey; 
    52.         this.jbpmService=jbpmService; 
    53.     }*/  
    54.                       
    55.       
    56.     //动态代理类仅仅能代理接口(不支持抽象类),代理类都须要实现InvocationHandler类,实现invoke方法。

      该invoke方法就是调用被代理接口的全部方法时须要调用的,该invoke方法返回的值是被代理接口的一个实现类       

    57.     public class LogHandler1 implements InvocationHandler{          
    58.     // 目标对象    
    59.     private Object targetObject;    
    60.     //绑定关系,也就是关联到哪个接口(与详细的实现类绑定)的哪些方法将被调用时,运行invoke方法。                
    61.     public Object newProxyInstanceStart(Object targetObject){    
    62.         this.targetObject=targetObject;    
    63.         //该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例      
    64.         //第一个參数指定产生代理对象的类载入器,须要将其指定为和目标对象同一个类载入器    
    65.         //第二个參数要实现和目标对象一样的接口,所以仅仅须要拿到目标对象的实现接口    
    66.         //第三个參数表明这些被拦截的方法在被拦截时须要运行哪个InvocationHandler的invoke方法    
    67.         //依据传入的目标返回一个代理对象    
    68.         return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),    
    69.                 targetObject.getClass().getInterfaces(),this);    
    70.     }    
    71.         
    72.     @Override    
    73.     //关联的这个实现类的方法被调用时将被运行    
    74.    // InvocationHandler接口的方法。proxy表示代理,method表示原对象被调用的方法,args表示方法的參数    
    75.     public Object invoke(Object proxy, Method method, Object[] args)    
    76.             throws Throwable {    
    77.         System.out.println("start-->>");    
    78.         for(int i=0;i<args.length;i++){    
    79.             System.out.println(args[i]);    
    80.         }    
    81.         Object ret=null;    
    82.         try{    
    83.             //原对象方法调用前处理日志信息    
    84.             System.out.println("satrt-->>");   
    85.                                
    86.             //启动流程  
    87.             //调用目标方法    
    88.             Leave leave=(Leave)args[0];            
    89.             // 用来设置启动流程的人员ID,引擎会自己主动把用户ID保存到activiti:initiator中  
    90.             try {  
    91.             identityService.setAuthenticatedUserId(leave.getUserId());                                  
    92.             ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("ChangeCourse", businessKey, variables);  
    93.             String processInstanceId = processInstance.getId();  
    94.               
    95.             leave.setProcessInstanceId(processInstanceId);  
    96.             logger.debug("start process of {key={}, bkey={}, pid={}, variables={}}"new Object[]{"ChangeCourse", processInstanceId, variables});  
    97.             } finally {  
    98.                 identityService.setAuthenticatedUserId(null);  
    99.             }  
    100.             args[0]=leave;  
    101.             ret=method.invoke(targetObject, args);    
    102.               
    103.             //调用完毕当前结点  
    104.             // >> 办理完第1个任务“提交申请”        
    105.             //jbpmService.completeFirstTask(pi);    
    106.               
    107.             //原对象方法调用后处理日志信息    
    108.             System.out.println("success-->>");    
    109.         }catch(Exception e){    
    110.             e.printStackTrace();    
    111.             System.out.println("error-->>");    
    112.                 throw e;    
    113.             }    
    114.             return ret;    
    115.         }             
    116.     }     
    117.   
    118. }  

    [java] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. /** 
    2.      * 任务列表ERROR [stderr] (http-localhost/127.0.0.1:8080-3) ScriptEngineManager providers.next(): javax.script.ScriptEngineFactory: Provider com.sun.script.javascript.RhinoScriptEngineFactory not found 
    3.      * 
    4.      * @param leave 
    5.      */  
    6.     @RequestMapping(value = "list/task")  
    7.     public ModelAndView taskList(HttpSession session, HttpServletRequest request) {  
    8.         List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();  
    9.         String userId = UserUtil.getUserFromSession(session).getId();  
    10.         results=abstractTaskList(userId);         
    11.         return new ModelAndView("/oa/leave/taskList","results",results);  
    12.                                  
    13.     }  

    [java] view plain copy
     print?

    在CODE上查看代码片派生到我的代码片

    1. /** 
    2.      * 抽象出来的查看任务列表。与基本业务无关 
    3.      * 
    4.      * @param userId 用户id 
    5.      * @return 
    6.      */  
    7.     public List<Map<String, Object>> abstractTaskList(String userId){  
    8.          List<Leave> results = new ArrayList<Leave>();  
    9.          // 依据当前人的ID查询  
    10.          TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);          
    11.          List<Task> tasks = taskQuery.list();       
    12.          int i=0;        
    13.            
    14.          List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();  
    15.          // 依据流程的业务ID查询实体并关联  
    16.          for (Task task : tasks) {  
    17.              String processInstanceId = task.getProcessInstanceId();  
    18.              ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).active().singleResult();  
    19.              String businessKey = processInstance.getBusinessKey();  
    20.              if (businessKey == null) {  
    21.                  continue;  
    22.              }   
    23.                
    24.              Map<String, Object> map = new HashMap<String, Object>();  
    25.                
    26.              Leave leave = leaveBean.findEntityById(businessKey);  
    27.                
    28.             //leave.setProcessInstance(processInstance);  
    29.             //leave.setProcessDefinition(getProcessDefinition(processInstance.getProcessDefinitionId()));                     
    30.         //leave.setTask(task);  
    31.               
    32.              map.put("leave", leave);//存入“申请信息”  
    33.              map.put("task", task);  
    34.              map.put("processDefinition", getProcessDefinition(processInstance.getProcessDefinitionId()));  
    35.              map.put("processInstance", processInstance);//存入“流程实例”  
    36.              mapList.add(map);  
    37.              /*Leave leave=updateEntity(processInstance,task,businessKey); 
    38.              results.add(leave); */  
    39.              i=i+1;  
    40.          }  
    41.         return mapList;  
    42.     }  

    [java] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. /** 
    2.      * 读取执行中的流程实例(查看我的申请)involvedUser(userId)(涉及到的用户) 
    3.      * 
    4.      * @return 
    5.      */  
    6.     @RequestMapping(value = "list/running")  
    7.     public ModelAndView runningList(HttpSession session,HttpServletRequest request) {  
    8.         String userId = UserUtil.getUserFromSession(session).getId();  
    9.         List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();  
    10.         results=abstractRuningList(userId);  
    11.     
    12.         return new ModelAndView ("/oa/leave/running","results",results);  
    13.        }  

    [java] view plain copy
     print?

    在CODE上查看代码片派生到我的代码片

    1. /** 
    2.      * 抽象出来读取执行中的流程实例(查看我的申请)。与基本业务无关 
    3.      * 
    4.      * @param userId 用户id 
    5.      * @return 
    6.      */  
    7.     public List<Map<String, Object>> abstractRuningList(String userId){  
    8.         List<Leave> results = new ArrayList<Leave>();  
    9.         ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery().processDefinitionKey("ChangeCourse").involvedUser(userId).active().orderByProcessInstanceId().desc();//依据流程定义Key查询流程实例  
    10.         List<ProcessInstance> list = query.list();  
    11.         List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();  
    12.         // 关联业务实体  
    13.         for (ProcessInstance processInstance : list) {  
    14.             String businessKey = processInstance.getBusinessKey();  
    15.             if (businessKey == null) {  
    16.                 continue;  
    17.             }  
    18.             // 设置当前任务信息  
    19.             List<Task> tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).active().orderByTaskCreateTime().desc().listPage(01);  
    20.             Map<String, Object> map = new HashMap<String, Object>();  
    21.                
    22.             Leave leave = leaveBean.findEntityById(businessKey);  
    23.               
    24.             /*leave.setProcessInstance(processInstance); 
    25.             leave.setProcessDefinition(getProcessDefinition(processInstance.getProcessDefinitionId()));                  
    26.             leave.setTask(tasks.get(0));*/  
    27.               
    28.              map.put("leave", leave);//存入“考试信息”  
    29.              map.put("task", tasks.get(0));  
    30.              map.put("processDefinition", getProcessDefinition(processInstance.getProcessDefinitionId()));  
    31.              map.put("processInstance", processInstance);//存入“流程实例”  
    32.              mapList.add(map);  
    33.              /*Leave leave=updateEntity(processInstance,task,businessKey); 
    34.              results.add(leave); */  
    35.               
    36.               
    37.             //Leave leave=updateEntity(processInstance,tasks.get(0),businessKey);  
    38.               
    39.               
    40.         }  
    41.         return mapList;  
    42.     }  

    [java] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1. /** 
    2.      * 读取完毕的流程实例(已经完毕的流程申请-我) 
    3.      * 
    4.      * @return 
    5.      */  
    6.     @RequestMapping(value = "list/finished")  
    7.     public ModelAndView finishedList(HttpSession session,HttpServletRequest request) {  
    8.          String userId = UserUtil.getUserFromSession(session).getId();    
    9.          List<Leave> results = new ArrayList<Leave>();  
    10.          HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().processDefinitionKey("ChangeCourse").involvedUser(userId).finished().orderByProcessInstanceEndTime().desc();  
    11.          List<HistoricProcessInstance> list = query.list();  
    12.          List<Map<String, Object>> mapList = new ArrayList<Map<String, Object>>();  
    13.          // 关联业务实体  
    14.          for (HistoricProcessInstance historicProcessInstance : list) {  
    15.              Map<String, Object> map = new HashMap<String, Object>();  
    16.              String businessKey = historicProcessInstance.getBusinessKey();  
    17.              Leave leave = leaveBean.findEntityById(businessKey);  
    18.             /* leave.setProcessDefinition(getProcessDefinition(historicProcessInstance.getProcessDefinitionId())); 
    19.              leave.setHistoricProcessInstance(historicProcessInstance);             
    20.              results.add(leave);*/   
    21.              map.put("leave", leave);//存入“申请信息”           
    22.              map.put("processDefinition", getProcessDefinition(historicProcessInstance.getProcessDefinitionId()));  
    23.              map.put("historicProcessInstance", historicProcessInstance);//存入“流程实例”  
    24.              mapList.add(map);  
    25.                
    26.          }  
    27.           
    28.         return new ModelAndView("/oa/leave/finished","results",mapList);  
    29.     }  

    [java] view plain copy
     print?在CODE上查看代码片派生到我的代码片
    1.  /** 
    2.      * 完毕任务 
    3.      * 
    4.      * @param id 
    5.      * @return 
    6.      */  
    7.     @RequestMapping(value = "/complete/{id}", method = {RequestMethod.POST, RequestMethod.GET})  
    8.     @ResponseBody  
    9.     public String complete(@PathVariable("id") String taskId, Variable var) {  
    10.         try {   
    11.             //deptLeaderPass=true or  hrBackReason=666, hrPass=false-----{leaderBackReason=78, deptLeaderPass=false}  
    12.             Map<String, Object> variables = var.getVariableMap();  
    13.             //taskService.getVariables(taskId);  
    14.             //Object variablesResult=variables.get("deptLeaderPass");             
    15.             //variablesResult=variables.get("hrPass");  
    16.               
    17.             taskService.complete(taskId, variables);              
    18.               
    19.             //获取map中的值  
    20. //            if(hrPass=true){  
    21. //              //更新业务表信息  
    22. //            }  
    23.             return "success";  
    24.         } catch (Exception e) {  
    25.             logger.error("error on complete task {}"new Object[]{taskId, e});  
    26.             return "error";  
    27.         }  
    28.     }  



    总结:

        对于在流程与业务的整合中应用动态代理也不知道是否符合AOP的理念,类似其它方面的流程操作还未抽取出来(交互太多),在这里记录一下学习Activiti的一个过程,在之后的尝试中能够换个方式。换个思路,直接将整个工作流应用抽取出来(请假,改动课程等)。

  • 相关阅读:
    [Dijkstra+堆优化]
    沈阳市 全国 沈阳市社会保险经办机构 信息查询 办保险用
    MS SQL 启用标识插入
    DataGridView导出到Word
    sql生成一个日期表
    精通BIRT:Eclipse商务智能报表工具开发实践指南
    BIRT-商务智能报表工具开发案例指南
    网页状态码
    javascript变量的作用域
    KAL1 LINUX 官方文档之工具---kali工具
  • 原文地址:https://www.cnblogs.com/yangykaifa/p/7102981.html
Copyright © 2011-2022 走看看