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

    继上篇博客:【整合篇】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 variables = new HashMap(); 
            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 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 variables,RuntimeService runtimeService,IdentityService identityService){
		this.variables=variables;
		this.businessKey=businessKey;
		this.runtimeService=runtimeService;
		this.identityService=identityService;
	}
	//想尝试能否根据其他方式传参,new的话太耗费资源
	/*public StartAbstractJBPM(String pdKey,Map 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>"); 
        		           	 
            //启动流程
            //调用目标方法  
            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> results = new ArrayList>();
    	String userId = UserUtil.getUserFromSession(session).getId();
    	results=abstractTaskList(userId);    	
    	return new ModelAndView("/oa/leave/taskList","results",results);
                               
    }

/**
     * 抽象出来的查看任务列表,与基本业务无关
     *
     * @param userId 用户id
     * @return
     */
	public List> abstractTaskList(String userId){
		 List results = new ArrayList();
	     // 根据当前人的ID查询
	     TaskQuery taskQuery = taskService.createTaskQuery().taskCandidateOrAssigned(userId);        
	     List tasks = taskQuery.list();     
	     int i=0;	   
	     
	     List> mapList = new ArrayList>();
	     // 根据流程的业务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 map = new HashMap();
	         
	         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> results = new ArrayList>();
    	results=abstractRuningList(userId);
  
    	return new ModelAndView ("/oa/leave/running","results",results);
       }

/**
     * 抽象出来读取运行中的流程实例(查看我的申请),与基本业务无关
     *
     * @param userId 用户id
     * @return
     */
	public List> abstractRuningList(String userId){
		List results = new ArrayList();
		ProcessInstanceQuery query = runtimeService.createProcessInstanceQuery().processDefinitionKey("ChangeCourse").involvedUser(userId).active().orderByProcessInstanceId().desc();//根据流程定义Key查询流程实例
    	List list = query.list();
    	List> mapList = new ArrayList>();
    	// 关联业务实体
        for (ProcessInstance processInstance : list) {
            String businessKey = processInstance.getBusinessKey();
            if (businessKey == null) {
                continue;
            }
            // 设置当前任务信息
            List tasks = taskService.createTaskQuery().processInstanceId(processInstance.getId()).active().orderByTaskCreateTime().desc().listPage(0, 1);
            Map map = new HashMap();
	         
            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 results = new ArrayList();
         HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery().processDefinitionKey("ChangeCourse").involvedUser(userId).finished().orderByProcessInstanceEndTime().desc();
         List list = query.list();
         List> mapList = new ArrayList>();
         // 关联业务实体
         for (HistoricProcessInstance historicProcessInstance : list) {
        	 Map map = new HashMap();
             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 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的一个过程,在之后的尝试中可以换个方式,换个思路,直接将整个工作流应用抽取出来(请假,修改课程等)。



你可能感兴趣的:(JAVA,工作流)