首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

activiti学习文件21-架构描述

2012-10-23 
activiti学习资料21--架构描述Activiti学习资料Activiti是业界很流行的java工作流引擎,关于Activiti与JBPM

activiti学习资料21--架构描述

Activiti学习资料

Activiti是业界很流行的java工作流引擎,关于Activiti与JBPM5的关系和如何选择不是本文要讨论的话题,相关内容可以baidu一下。Activiti从架构角度看是比较优秀的,是很面向对象的,是我所阅读过的代码结构很棒的开源软件,个人认为比Spring,Hibernate的要好。

Activiti的基础编程框架



activiti学习文件21-架构描述

Activiti基于Spring,ibatis等开源中间件作为软件平台,在此之上构建了非常清晰的开发框架。上图列出了Activiti的核心组件。

1.ProcessEngine:流程引擎的抽象,对于开发者来说,它是我们使用Activiti的facade,通过它可以获得我们需要的一切服务。

2.XXService(TaskService,RuntimeService,RepositoryService...):Activiti按照流程的生命周期(定义,部署,运行)把不同阶段的服务封装在不同的Service中,用户可以非常清晰地使用特定阶段的接口。通过ProcessEngine能够获得这些Service实例。TaskService,RuntimeService,RepositoryService是非常重要的三个Service:

TaskService:流程运行过程中,与每个任务节点相关的接口,比如complete,delete,delegate等等

RepositoryService:流程定义和部署相关的存储服务。

RuntimeService:流程运行时相关服务,如startProcessInstanceByKey.

 

关于ProcessEngine和XXService的关系,可以看下面这张图:

activiti学习文件21-架构描述

 

 

3.CommandContextIntercepter(CommandExecutor):Activiti使用命令模式作为基础开发模式,上面Service中定义的各个方法都对应相应的命令对象(xxCmd), Service把各种请求委托给xxCmd,xxCmd来决定命令的接收者,接收者执行后返回结果。而CommandContextIntercepter顾名思义,它是一个拦截器,拦截所有命令,在命令执行前后执行一些公共性操作。比如CommandContextIntercepter的核心方法:

 

(图2:TaskEntity类)

TaskEntity实现了3个接口:Task,DelegateTask和PersistentObject。其中PersistentObject是一个声明接口,表明TaskEntity需要持久化。接口是一种角色的声明,是一份职责的描述而TaskEntity就是这个角色的具体扮演者,因此TaskEntity必须承担如complete,delegate等职责。

但是这里有些遗憾的是像complete这么重要的行为居然没有在3个接口中描述(难道是因为工期紧张?^_^),因此“面向抽象”编程对于TaskEntity来说还没有完全做到。但至少Activiti告诉我们:

1)牢记面向抽象编程,把职责拆分为不同的接口,让接口来体现对象的职责,而不用去关心这份职责具体由哪个对象实现;

2)entity其实可以也应该是真正的对象。

 

5.Activiti的上下文组件(Context)

上下文(Context)用来保存生命周期很长的、全局性的信息。Activiti的Context类(在org.activiti.engine.impl.context包下)保持如下三类信息:

 

activiti学习文件21-架构描述

(图3:Context类)

CommandContext:命令上下文,保持每个命令需要的必要资源,如持久化需要的session。

ProcessEngineConfigurationImpl:流程引擎相关的配置信息。它是整个引擎的全局配置信息,mailServerHost,DataSource等。单例。该实例在流程引擎创建时被实例化,其调用stack如下图:

activiti学习文件21-架构描述

(图4:ProcessEngineConfiguration的初始化)

ExecutionContext:刚看到这个类感觉有些奇怪,不明白其作用是什么。看其代码持有ExecutionEntity这个实例。而ExecutionEntity是Activiti中非常重要的一个类,//TODO

 

 

6.Activiti的持久化框架(组件)

Activiti使用ibatis作为ORMapping工具。在此基础之上Activiti设计了自己的持久化框架,看一张图:

activiti学习文件21-架构描述

 

(图5:Activiti持久化框架)

 

顶层接口是Session和SessionFactory,这都非常好理解了。

Session有两个实现类:

DbSqlSession:简单点说,DbSqlSession负责sql表达式的执行。

AbstractManager:简单点说,AbstractManager及其子类负责面向对象的持久化操作

同理DbSqlSessionFactory与GenericManagerFactory的区别就很好理解了。

 

持久化框架也是在流程引擎建立时初始化的,具体见图4.

 

7.Event-Listener 组件

Activiti允许客户端代码介入流程的执行。为此提供了一个基础组件,看图:

activiti学习文件21-架构描述

(图6:用户代码介入流程的基础组件)

用户可以介入的代码类型包括:TaskListener,JavaDelegate,Expression,ExecutionListener。

ProcessEngineConfigurationImpl持有DelegateInterceptor的某个实例,这样就可以随时非常方便地调用handleInvocation

 

8.Cache 组件

对Activiti的cache实现很感兴趣,但现在我了解到的情况(也许还没有了解清楚)其cache的实现还是很简单的,在DbSqlSession中有cache实现:

 

(图7:异步执行组件核心类)

JobExecutor是异步执行组件的核心类,其包含三个主要属性:

1)JobAcquisitionThread jobAccquisitionThread:执行任务的线程 extends java.lang.Thread

2)BlockingQueue<Runnable> threadPoolQueue

3)ThreadPoolExecutor threadPoolExecutor:线程池

 

方法ProcessEngines在引擎启动时调用JobExecutor.start,JobAcquisitionThread 线程即开始工作,其run方法不断循环执行AcquiredJobs中的job,执行一次后线程等待一定时间直到超时或者JobExecutor.jobWasAdded方法因为有新任务而被调用。

 

这里发现有一处设计的不够好:JobAcquisitionThread 与JobExecutor之间的关系是如此紧密(你中有我,我中有你),那么可以把JobAcquisitionThread 作为JobExecutor的内部类来实现,同时把ThreadPoolExecutor threadPoolExecutor交给JobAcquisitionThread 来管理,JobExecutor只负责接受任务以及启动、停止等更高级的工作,具体细节委托给JobAcquisitionThread ,责任分解,便于维护,JobExecutor的代码也会看起来更清晰。

 

 

10.PVM

PVM:Process Virtal Machine,流程虚拟机API暴露了流程虚拟机的POJO核心,流程虚拟机API描述了一个工作流流程必备的组件,这些组件包括:

PvmProcessDefinition:流程的定义,形象点说就是用户画的那个图。静态含义。

PvmProcessInstance:流程实例,用户发起的某个PvmProcessDefinition的一个实例,动态含义。

PvmActivity:流程中的一个节点

PvmTransition:衔接各个节点之间的路径,形象点说就是图中各个节点之间的连接线。

PvmEvent:流程执行过程中触发的事件

 

以上这些组件很好地对一个流程进行了建模和抽象。每个组件都有很清晰的角色和职责划分。另外,有了这些API,我们可以通过编程的方式,用代码来“画”一个流程图并让他run起来,例如:

/**  * @author Tom Baeyens  */  public interface PvmActivity extends PvmScope {        boolean isAsync();      PvmScope getParent();      List<PvmTransition> getIncomingTransitions();      List<PvmTransition> getOutgoingTransitions();        PvmTransition findOutgoingTransition(String transitionId);  }  

把思路拉回来,我们继续看activityBehavior.signal方法内部的具体实现。

activiti-explorer源码下载地址:https://github.com/HSSC/activiti-explorer

热点排行