工作流Activiti介绍与应用工作流(workflow)就是工作流程的计算模型,即将工作流程中的工作如何前后组织在一起的逻辑和规则在计算机中以恰当的模型进行表示并对其实施计算。
我的理解就是:将部分或者全部的工作流程、逻辑让计算机帮你来处理,实现自动化。
1Activiti简介Activiti是由Alfresco软件在2010年5月17日发布的业务流程管理(BPM)框架,它是覆盖了业务流程管理,工作流,服务协作等领域的一个开源,灵活的,易扩展的可执行流程语言框架。
它实现了BPMN 2.0规范,可以发布设计好的流程定义,并通过api进行流程调度。
1.1A ctiviti基础编程框架Activiti的基础编程框架如下:Activiti基于Spring,ibatis等开源中间件作为软件平台,在此之上构建了非常清晰的开发框架。
上图列出了Activiti的核心组件。
1.ProcessEngine:流程引擎的抽象,对于开发者来说,它是我们使用Activiti的外观(façade),通过它可以获得我们需要的一切服务。
2.XXService(TaskService,RuntimeService,RepositoryService...):Activiti按照流程的生命周期(定义,部署,运行)把不同阶段的服务封装在不同的Service中,用户可以非常清晰地使用特定阶段的接口。
通过ProcessEngine能够获得这些Service 实例。
1.2A ctiviti重要服务类ProcessEngine:流程引擎的抽象,通过它我们可以获得我们需要的一切服务。
RepositoryService: Activiti中每一个不同版本的业务流程的定义都需要使用一些定义文件,部署文件和支持数据(例如BPMN2.0 XML文件,表单定义文件,流程定义图像文件等),这些文件都存储在Activiti内建的Repository中。
RepositoryService提供了对repository 的存取服务。
TaskService:在Activiti业务流程定义中每一个执行节点都被称作一个Task,流程运行过程中,与每个任务节点相关的接口,比如complete, delete,delegate等等都是TaskService提供的。
IdentityService: Activiti中内置了用户以及组管理的功能,必须使用这些用户和组的信息才能获取到相应的Task。
IdentityService提供了对Activiti 系统中的用户和组的管理功能。
FormService:Activiti中的流程和Task状态均可关联业务相关的数据。
通过FormService可以存取启动和完成任务所需要的表单数据。
RuntimeService:在Activiti中,每当一个流程定义被启动一次之后,都会生成一个相应的流程对象实例。
RuntimeService提供了启动流程、查询流程实例、设置获取流程实例变量等功能。
此外它还提供了对流程部署,流程定义和流程实例的存取服务。
. ManagementService: ManagementService提供了对Activiti流程引擎的管理和维护功能,这些功能不在工作流驱动的应用程序中使用,主要用于Activiti系统的日常维护。
HistoryService: HistoryService用于获取正在运行或已经完成的流程实例的信息,与RuntimeService中获取的流程信息不同,历史信息包含已经持久化存储的永久信息,并已经被针对查询优化。
关于ProcessEngine和XXService的关系,可以看下面这张图:2Activiti深入2.1A ctiviti配置类分析ProcessEngineConfiguration类的结构图如下图:正如上图所示,ProcessEngineConfiguration是全部配置类的父类,有一个ProcessEngineConfigurationImpl子类,ProcessEngineConfigurationImpl下面有三个直接的子类,其中ProcessEngineConfiguration和ProcessEngineConfigurationImpl都是抽象类。
这个类是我们编程时第一个使用的类,有了这个类的层级结构,我们就比较容易理解通过该类获取各种具体实现的ProcessEngineConfiguration类的实例了。
ProcessEngineConfiguration.createProcessEngineConfigurationFromResourceDefa ult();ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("acti viti.cfg.xml");ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();通过上面的方法,可以获取流程引擎的配置类的实例,这些实例有的是通过配置文件进行配置的,有的则是通过程序的方法进行指定,比如:ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();生成这样的配置实例后,需要对该实例进行数据库连接相关的配置等等。
2.2Activiti命令执行器分析ACTIVITI 所有执行过程都是采用命令模式,使用命令执行器进行执行,这个可是从RuntimeServiceImpl启动流程的代码可以看出来:public ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey) {return commandExecutor.execute(newStartProcessInstanceCmd<ProcessInstance>(processDefinitionKey, null, businessKey, null));}为了了解命令执行commandExecutor,特分如下几节来说明它的构造,传递,以及命令执行执行的过车过你。
2.2.1命令执行器的构造命令执行器是一个采用拦截器链式的结构,这个可以从如下的分析得出:commandExecutor对象是首先在ProcessEngineConfigurationImpl的初始化方法中产生:protected void initCommandExecutor() {if (commandExecutor==null) {CommandInterceptor first = initInterceptorChain(commandInterceptors);commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);}}而这个命令执行器commandExecutor的构造过程中跟commandInterceptors中的第一个命令拦截器有关,而commandInterceptors是命令拦截器的列表。
protected void initCommandInterceptors() {if (commandInterceptors==null) {commandInterceptors = new ArrayList<CommandInterceptor>();if (customPreCommandInterceptors!=null) {commandInterceptors.addAll(customPreCommandInterceptors);}commandInterceptors.addAll(getDefaultCommandInterceptors());if (customPostCommandInterceptors!=null) {commandInterceptors.addAll(customPostCommandInterceptors);}commandInterceptors.add(commandInvoker);}}protected Collection< ? extends CommandInterceptor> getDefaultCommandInterceptors() { List<CommandInterceptor> interceptors = new ArrayList<CommandInterceptor>();interceptors.add(new LogInterceptor());CommandInterceptor transactionInterceptor = createTransactionInterceptor();if (transactionInterceptor != null) {interceptors.add(transactionInterceptor);}interceptors.add(new CommandContextInterceptor(commandContextFactory, this));return interceptors;}同时每个拦截器又是通过next域的方式将不同的拦截器进行链接形成一个链接结构,这个可以从initInterceptorChain方法可以看出来:protected CommandInterceptor initInterceptorChain(List<CommandInterceptor> chain) { if (chain==null || chain.isEmpty()) {throw new ActivitiException("invalid command interceptor chain configuration: "+chain);}for (int i = 0; i < chain.size()-1; i++) {chain.get(i).setNext( chain.get(i+1) );}return chain.get(0);}2.2.2命令执行器的传递命令执行器commandExecutor对象在ProcessEngineConfigurationImpl的初始化方法中生成,那么为什么它会在RuntimeService等service对象中获取呢?依然回到ProcessEngineConfigurationImpl初始化过程,初始化过程会调用initServices方法,将runtimeService等Service实例与该命令执行体commandExecutor进行绑定。