继博客【思想篇】工作流技术JBPM开发入门(三)的实现完成!应对业务的变化。
其实这次对于工作流的学习大概分了3主要个阶段:
1,结合业务开发一个简单的工作流,应对业务的变更
2,结合业务开发业务结点,使流程管理业务
3,抽象实体,使开发出来的业务结点能够复用
下面要说的是第一阶段:
启动流程实例:
/** 提交申请 */ public String submit() throws Exception { // 封装申请信息 Application application = new Application(); title=new String(title.getBytes("iso-8859-1"),"utf-8"); reason=new String(reason.getBytes("iso-8859-1"),"utf-8"); application.setApplicant(getCurrentUser()); // 申请人,当前用户 application.setTitle(title); application.setReason(reason); String processDefinitionKeyStr=new String(processDefinitionKey.getBytes("iso-8859-1"),"utf-8"); application.setProcessDefinitionKey(processDefinitionKeyStr); // 调用业务方法(保存申请信息,并启动流程开始流转) applicationService.submit(application); return "toMyApplicationList"; // 成功后转到"我的申请查询" }
对应的流程代码:
public void submit(Application application) { // 1,设置属性并保存application application.setApplyTime(sdf.format(new Date())); // 申请时间,当前时间 application.setStatus(Application.STATUS_RUNNING); // 2,启动程程实例开始流转 // >> 准备流程变量 Map<String, Object> variablesMap = new HashMap<String, Object>(); variablesMap.put("application", application); // >> 启动流程实例,并带上流程变量(当前的申请信息) //获取流程定义的key String pdKey = application.getProcessDefinitionKey(); //根据流程定义的key值和相应的流程变量启动流程 ProcessInstance pi = processEngine.getExecutionService()// .startProcessInstanceByKey(pdKey, variablesMap); application.setExecuteId(pi.getId()); getSession().save(application); // 保存 // >> 办理完第1个任务“提交申请” Task task = processEngine.getTaskService()// .createTaskQuery()// 查询出本流程实例中当前仅有的一个任务“提交申请” .processInstanceId(pi.getId())// .uniqueResult(); processEngine.getTaskService().completeTask(task.getId()); }
审批处理:
/** 审批处理 */ public String approve() throws Exception { // 封装 ApproveInfo approveInfo = new ApproveInfo(); comment=new String(comment.getBytes("iso-8859-1"),"utf-8"); approveInfo.setComment(comment); approveInfo.setApproval(approval); approveInfo.setApplication(applicationService.getById(applicationId)); approveInfo.setApprover(getCurrentUser()); // 审批人,当前登录用户 approveInfo.setApproveTime(sdf.format(new Date())); // 当前时间 if(outcome!=null){ // 调用用业务方法(保存本次审批信息,并办理完任务,并维护申请的状态) outcome=new String(outcome.getBytes("iso-8859-1"),"utf-8"); } applicationService.approve(approveInfo, taskId, outcome); return "toMyTaskList"; // 成功后转到待我审批页面 }
对应的流程代码:
//办理任务 public void approve(ApproveInfo approveInfo, String taskId, String outcome) { // 1,保存本次审批信息 getSession().save(approveInfo); // 2,办理完任务 Task task = processEngine.getTaskService().getTask(taskId); // 一定要先取出Task对象,再完成任务,否则拿不到,因为执行完就变成历史信息了。 if (outcome == null) { processEngine.getTaskService().completeTask(taskId); } else { processEngine.getTaskService().completeTask(taskId, outcome); } // >> 取出所属的流程实例,如果取出的为null,说明流程实例执行完成了,已经变成了历史记录 ProcessInstance pi = processEngine.getExecutionService().findProcessInstanceById(task.getExecutionId()); // 3,维护申请的状态 Application application = approveInfo.getApplication(); if (!approveInfo.isApproval()) { // 如果本环节不同意,则流程实例直接结束,申请的状态为:未通过 if (pi != null) { // 如果流程还未结束 processEngine.getExecutionService().endProcessInstance(task.getExecutionId(), ProcessInstance.STATE_ENDED); } application.setStatus(Application.STATUS_REJECTED); } else { // 如果本环节同意,而且本环节是最后一个环节,则流程实例正常结束,申请的状态为:已通过 if (pi == null) { // 本环节是最后一个环节,即流程已经结束了 application.setStatus(Application.STATUS_APPROVED); } } getSession().update(application); }
待我审批:
/** 待我审批(我的任务列表) */ public String myTaskList() throws Exception { List<TaskView> taskViewList = applicationService.getMyTaskViewList(getCurrentUser()); //List<TaskView> taskViewList = applicationService.getMyTaskViewList(user); ActionContext.getContext().put("taskViewList", taskViewList); return "myTaskList"; }
对应的流程代码:(此时需要查看流程的数据以及业务数据的共存)
public List<TaskView> getMyTaskViewList(User currentUser) { // 查询我的任务列表 String userId = currentUser.getUsername(); // 约定使用loginName作为JBPM用的用户标识符 List<Task> taskList = processEngine.getTaskService().findPersonalTasks(userId); // 找出每个任务对应的申请信息 List<TaskView> resultList = new ArrayList<TaskView>(); for (Task task : taskList) { Application application = (Application) processEngine.getTaskService().getVariable(task.getId(), "application"); resultList.add(new TaskView(task, application)); } // 返回“任务--申请信息”的结果 return resultList; }
TaskView实体:
public class TaskView { private Task task; private Application application; public TaskView(Task task, Application application) { this.task = task; this.application = application; } public Task getTask() { return task; } public void setTask(Task task) { this.task = task; } public Application getApplication() { return application; } public void setApplication(Application application) { this.application = application; } }
查询流转记录:此时的这个流转记录其实调用的是自己的业务,跟流程并没有关系,因为在这个业务中我们共建立了两个实体类,申请实体类,办理实体类,一个申请对应多个办理,它们之间是一对多的关系。当然我们也可以不建立办理实体类,而是将所有的办理结果均存到流程变量中,也可以查看申请的流转记录。(多种方式)
通过以上的代码,大家不难发现,所有的业务和工作流紧密结合,这就要求所有的程序员去熟悉工作流的使用,而且它们之间的耦合程度高,这就给维护带来了麻烦,但是即使是这样的实现,它也能应对一些变化。例如:学生申请修改课程的业务,导员审批--教秘审批,最终审批结束。如果我们在导员审批之前要加上班长审批这一环节,对于我们来说代码无需修改就可以实现。但是这样就真的万事大吉了吗?这也就带来了【思想篇】工作流技术JBPM开发入门(四)篇博客的问题所在.