继博客【思想篇】工作流技术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开发入门(四)篇博客的问题所在.