Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

       UFLO是一套基于JAVA的流程引擎,它即可以用在基于J2EE的B/S系统之上,也可以用于基于J2EE的C/S系统之中。所以UFLO在设计之初就不与任何UI表现层绑定,它所要做的就是提供一系列的可供外部调用的API接口,对于我们的业务系统而言,可以调用UFLO中提供的API,实现业务流程的开启、任务的开始与完成等操作。

       我们知道,UFLO中有三个子项目,分别是uflo 我们知道,UFLO中有两个子项目,分别是uflo-core、uflocore与uflo-console与ufloconsole。uflo-client。uflo-core提供了流程运行的核心环境,负责整个流程生命周期的管理工作;uflo-console则是一个基于dorado7表现层的分支项目,这个项目中提供了B/S项目中基于dorado7的流程模版控制与测试中心、提供了用户待办页面及节假日配置等流程引擎运行的辅助模块;最后一个uflo-client则是提供给我们的程序员使用的,通过调用uflo-client模块中的ProcessClient与其中的TaskClient就可实现在我们的业务系统与流程引擎的交互。下面是开启一个流程实例操作的代码片段。console则是一个基于WEB表现层的分支项目,这个项目中提供了基于网页的流程模版控制与测试中心、提供了用户待办页面及节假日配置等流程引擎运行的辅助模块;通过调用uflo-core模块中的ProcessService与其中的TaskService就可实现在我们的业务系统与流程引擎的交互。下面是开启一个流程实例操作的代码片段。

Code Block
title开启流程示例代码
linenumberstrue
languagejava
import javax.annotation.Resource;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.uflo.client.service.ProcessClientProcessService;
import com.bstek.uflo.service.StartProcessInfo;
public class BusinessTest {
	@Resource(name=ProcessClientProcessService.BEAN_ID)
	private ProcessClientProcessService processClientprocessService;
	public void saveDataAndStartProcess(BusinessData data){
		String primaryKeyValue=saveBusinessData(data);
		StartProcessInfo info=new StartProcessInfo(ContextHolder.getLoginUserName());
		info.setBusinessId(primaryKeyValue);
		processClientprocessService.startProcessById(101, info);
	}
}

       从上面的代码中可以看到,在开始流程之前,我们首先将提交上业的BusinessData这个业务数据对象保存,保存后产生该对象的主键值primaryKeyValue,接下来创建一个StartProcessInfo 对象,将业务对象主键值赋给这个对象,并设置流程开启人,最后调用ProcessClient接口的ProcessInstance startProcessById(long processId,StartProcessInfo startProcessInfo)方法开启一个ID为101的流程模版对应的流程实例。在上面的代码当中,ProcessClient我们通过Spring注入到当前类中,ProcessClient配置在Spring中的Bean的ID就是ProcessClient方法开启一个ID为101的流程模版对应的流程实例。在上面的代码当中,ProcessService我们通过Spring注入到当前类中,ProcessService配置在Spring中的Bean的ID就是ProcessService.BEAN_ID的常量值,所以这里可以直接使用。

       下面我们再来看一段完成任务的业务代码:

Code Block
title完成任务示例代码
linenumberstrue
languagejava
import java.util.HashMap;
import java.util.Map;
import javax.annotation.Resource;
import com.bstek.bdf2.core.context.ContextHolder;
import com.bstek.uflo.client.service.TaskClientTaskService;
import com.bstek.uflo.service.StartProcessInfo;
public class BusinessTest {
	@Resource(name=TaskClientTaskService.BEAN_ID)
	private TaskClientTaskService taskClienttaskService;
	public void saveDataAndStartProcess(BusinessData data,long taskId){
		saveBusinessData(data);
		Map<String,Object> variables=new HashMap<String,Object>();
		variables.put("businessName", data.getName());
		variables.put("businessOwner", data.getBusinessOwner());
		taskClienttaskService.start(taskId);
		taskClienttaskService.complete(taskId,variables);
	}
}

       比较开始流程的代码片段,我们会发现操作模式基本一样,都是先进行业务数据操作(保存、更新之类),再进行流程操作(开始流程实例或完成任务),在这段完成任务的示例代码当中,首先调用saveBusinessData方法来保存提交上来的业务数据,接下来创建一个Map集合,用于存放需要写入流程的流程变量的值,这里的我们从BusinessData中取了两个值放入这个Map,接下来调用TaskClient的start方法开始指定的人工任务 比较开始流程的代码片段,我们会发现操作模式基本一样,都是先进行业务数据操作(保存、更新之类),再进行流程操作(开始流程实例或完成任务),在这段完成任务的示例代码当中,首先调用saveBusinessData方法来保存提交上来的业务数据,接下来创建一个Map集合,用于存放需要写入流程的流程变量的值,这里的我们从BusinessData中取了两个值放入这个Map,接下来调用TaskService的start方法开始指定的人工任务(UFLO中人工任务的完成必须要先开始,某些时候对于处理周期比较长的人工任务,可以先开始,再不断设置处理进度progress的值,最后再完成,这里就直接开始后完成),最后调用TaskClient的complete方法完成指定人工任务并回将流程变量的Map写入到流程实现。

       同开始流程的代码一样,TaskClient也是通过Spring注入,其在Spring中Bean的ID为TaskClient 同开始流程的代码一样,TaskService也是通过Spring注入,其在Spring中Bean的ID为TaskService.BEAN_ID。

       前面提到,UFLO的使用支持嵌入式与独立服务两种方式,但对于我们程序员来说,它只需要使用uflo-client模块中的ProcessClient与其中的TaskClient与我们的业务系统交互即可,究竟项目做好之后,采用哪种部署方式,我们的uflo-client模块中的ProcessClient与其中的TaskClient都可以通过设置一个外部属性实现自由转换,这个属性就是uflo.restAccessBaseUrl,该属性值的作用就是指定独立部署的远程uflo server的地址。默认该属性值为空,那么我们的引擎就会认为我们采用的是嵌入式模式,所以它会通过访问我们项目内部配置的数据源实现与流程引擎数据库的互动;一旦我们定义了该属性的值,那么UFLO引擎就知道我们采用的是独立服务模式,它会通过该属性定义的URL值来访问远程的uflo server,实现本地业务逻辑与远程流程引擎的交互。       ProcessClient对于我们程序员来说,主要是实现业务流程的开启、流程模版与实例的删除、流程模版与变量的获取等操作;而TaskClient则提供了大量针对人工任务的操作。 ProcessService对于我们程序员来说,主要是实现业务流程的开启、流程模版与实例的删除、流程模版与变量的获取等操作;而TaskService则提供了大量针对人工任务的操作。在这两个接口当中,我们为每个方法都添加了详细的注释,使用时查看注释应该就可以明确具体用法。

...