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

目录
相关文章
|
6月前
22activiti - 流程管理定义(查询流程状态)
22activiti - 流程管理定义(查询流程状态)
54 0
|
6月前
|
数据库
20activiti - 流程管理定义(查询个人任务)
20activiti - 流程管理定义(查询个人任务)
40 0
20activiti - 流程管理定义(查询个人任务)
|
6月前
|
存储 数据库
13activiti - 流程管理定义(部署流程定义)
13activiti - 流程管理定义(部署流程定义)
35 0
|
4月前
Activiti 流程发布
Activiti 流程发布
22 0
|
7月前
|
存储 Java API
流程引擎Activiti流程实例讲解
流程引擎Activiti流程实例讲解
141 0
|
8月前
|
监控 数据可视化 Java
高效流程引擎:深入探索 Activiti 工作流引擎
在现代的企业环境中,业务流程的自动化和优化变得越来越重要。Activiti,作为一款轻量级、可嵌入的工作流引擎,为企业提供了一种高效的方式来管理和执行各种业务流程。本文将为您详细介绍 Activiti 的核心概念、特性以及在业务流程管理中的应用。
291 0
|
Java 数据库连接 API
Activiti-流程操作2
Activiti-流程操作2
Activiti-流程操作2
|
Java API 数据库
Activiti-流程操作
Activiti-流程操作
Activiti-流程操作
|
存储 API 数据库
工作流中的流程追溯!Activiti框架的历史组件详细解析
本篇文章详细说明了工作流Activiti框架中的历史组件,这个组件用于捕获发生在进程执行中的信息并对这些信息进行永久保存,在流程实例运行完成后,这些数据依旧保存在数据库中。工作流Activiti框架中提供了对历史数据的查询方法。最后介绍了历史组件的相关配置以及使用历史组件中的数据进行流程审计。通过对历史组件的学习,可以方便地对工作流的流程进行追溯。
527 0
工作流中的流程追溯!Activiti框架的历史组件详细解析
|
存储 Java API
工作流中的数据持久化详解!Activiti框架中JPA的使用分析
本文介绍了工作流Activiti框架中流程数据的持久化,在工作流Acitiviti框架中JPA的使用方式。介绍了使用JPA实体的基本要求,JPA的使用配置以及JPA的具体用法。最后通过一个示例展示了工作流中的流程数据的持久化以及如何查询JPA变量和在Spring Bean中集成JPA使用。
274 0
工作流中的数据持久化详解!Activiti框架中JPA的使用分析