Activiti总体框架分析
參考資料
- activiti數據表結構
- Activiti 5.16 用戶手冊
- Activiti User Guide
- activiti與BPMN
- activiti源碼
- activiti_doc文檔
Engine解析
| org.activiti.engine | 流程引擎公共API方法,均采用鏈式方式 一般通過ProcessEngineConfiguration創建 可以獲得的服務包括: RepositoryService RuntimeService TaskService IdentityService ManagementService HistoryService FormService |
| org.activiti.engine.impl | engine模塊的核心,包含了: pvm的實現 接口方法的實現 命令模式 |
| org.activiti.engine.cfg | 配置接口 |
| org.activiti.engine.ProcessEngine | 引擎接口 |
| org.activiti.engine.ProcessEngineConfiguration | 配置管理 |
| org.activiti.engine.ActivitiException | 基礎異常類 |
| org.activiti.engine.delegate | ? |
| org.activiti.engine.form | 表單信息,和FormService相關聯 |
| org.activiti.engine.history | 流程歷史信息,和HistoryService相關聯 |
| org.activiti.engine.identity | 用戶、組管理信息,和IdentityService相關聯 |
| org.activiti.engine.logging | 日志 |
| org.activiti.engine.management | 流程管理和控制信息,和ManagementService相關聯 |
| org.activiti.engine.repository | 流程資源信息,和RepositoryService相關聯 |
| org.activiti.engine.runtime | 流程運行時相關信息,和RuntimeService相關聯 |
| org.activiti.engine.task | 表示任務相關信息,和TaskService相關聯 |
1. org.activiti.engine
定義了流程管理服務的接口:RepositoryService、RuntimeService、?FormService、TaskService、HistoryService、IdentityService、?ManagementService?。
定義了引擎配置管理接口ProcessEngineConfiguration。
定義了activiti異常類ActivitiException。
org.activiti.engine是activiti的核心功能,控制工作流的流轉。幾個核心的類如下圖所示:
1.1 ProcessEngine
ProcessEngine接口繼承EngineServices,EngineServices包括很多工作流/BPM方法的服務,它們都是線程安全的。EngineServices提供的服務包括:
-
RepositoryService:提供了管理和控制流程定義的操作。
-
RuntimeService:提供了管理和控制流程實例的操作。
-
FormService:提供了管理流程表單的操作,即使不用FormService,activiti也可以完美運行。
-
TaskService:提供了任務管理的操作,包括實例任務掛起、激活、完成、暫停、查詢。
-
HistoryService:提供對歷史流程,歷史任務,歷史變量的查詢操作。
-
IdentityService:提供用戶和組管理的操作(創建,更新,刪除,查詢...)。
-
ManagementService:提供了查詢和管理異步操作(定時器,異步操作, 延遲暫停、激活等)的功能,它還可以查詢到數據庫的表和表的元數據。
EngineServices?代碼如下所示:
public interface EngineServices {RepositoryService getRepositoryService();RuntimeService getRuntimeService();FormService getFormService();TaskService getTaskService();HistoryService getHistoryService();IdentityService getIdentityService();ManagementService getManagementService();ProcessEngineConfiguration getProcessEngineConfiguration();}ProcessEngine?代碼如下所示:
public interface ProcessEngine extends EngineServices {/** the version of the activiti library */public static String VERSION = "5.17.0.2";/** The name as specified in 'process-engine-name' in* the activiti.cfg.xml configuration file.* The default name for a process engine is 'default */String getName();void close();}1.2 ProcessEngineConfiguration
ProcessEngineConfiguration是配置管理類,它管理的對象包括ProcessEngine,XXservice,數據庫session等。ProcessEngineConfiguration的配置,activiti默認會從activiti.cfg.xml中讀取,也可以在Spring的配置文件中讀取。ProcessEngineConfiguration的實現包括:
-
ProcessEngineConfigurationImpl繼承ProcessEngineConfiguration,實現了各種Service的初始化
-
StandaloneProcessEngineConfiguration是單獨運行的流程引擎,繼承ProcessEngineConfigurationImpl。代碼如下:
public class StandaloneProcessEngineConfiguration extends ProcessEngineConfigurationImpl {@Overrideprotected CommandInterceptor createTransactionInterceptor() {return null;} } -
StandaloneInMemProcessEngineConfiguration是單元測試時的輔助類,繼承StandaloneProcessEngineConfiguration,默認使用H2內存數據庫。數據庫表會在引擎啟動時創建,關閉時刪除。代碼如下所示:
public class StandaloneInMemProcessEngineConfiguration extends StandaloneProcessEngineConfiguration {public StandaloneInMemProcessEngineConfiguration() {this.databaseSchemaUpdate = DB_SCHEMA_UPDATE_CREATE_DROP;this.jdbcUrl = "jdbc:h2:mem:activiti";} } -
SpringProcessEngineConfiguration是Spring環境下使用的流程引擎。
-
JtaProcessEngineConfiguration單獨運行的流程引擎,并使用JTA事務。
1.3 ActivitiException
activiti的基礎異常類是org.activiti.engine.ActivitiException,一個非檢查異常。Activiti的異常都是通過org.activiti.engine.ActivitiException拋出,但存在以下特殊情況:
-
ActivitiWrongDbException:當Activiti引擎發現數據庫版本號和引擎版本號不一致時拋出。
-
ActivitiOptimisticLockingException:對同一數據進行并發方法并出現樂觀鎖時拋出。
-
ActivitiClassLoadingException:當無法找到需要加載的類或在加載類時出現了錯誤(比如,JavaDelegate,TaskListener等。
-
ActivitiObjectNotFoundException:當請求或操作的對應不存在時拋出。
-
ActivitiIllegalArgumentException:這個異常表示調用Activiti API時傳入了一個非法的參數,可能是引擎配置中的非法值,或提供了一個非法制,或流程定義中使用的非法值。
-
ActivitiTaskAlreadyClaimedException:當任務已經被認領了,再調用taskService.claim(...)就會拋出。
-
BpmnError:流程部署錯誤,如流程定義文件不合法。
-
JobNotFoundException:JOB不存在。
2. org.activiti.engine.impl
實現了流程管理服務RepositoryServiceImpl,?RuntimeServiceImpl,?FormServiceImpl,?TaskServiceImpl,?HistoryServiceImpl,?IdentityServiceImpl,?ManagementServiceImpl
實現流程虛擬機PVM
數據持久化,腳本任務,條件表達式EL的解析等等
命令接口的定義
| org.activiti.engine.impl.asyncexecutor | job調度,主要管理調度線程 |
| org.activiti.engine.impl.bpmn | 部署文件,BPMN元素管理 |
| org.activiti.engine.impl.calendar | 時間,日期管理 |
| org.activiti.engine.impl.cfg | ProcessEngineConfiguration的實現 |
| org.activiti.engine.impl.cmd | 命令模式的client,實現了各種命令 |
| org.activiti.engine.impl.context | 上下文定義文件,保存線程數據 |
| org.activiti.engine.impl.db | 數據庫基本增刪改操作 |
| org.activiti.engine.impl.delegate | 任務監聽 |
| org.activiti.engine.impl.el | 表達式解析,執行 |
| org.activiti.engine.impl.event | 事件 |
| org.activiti.engine.impl.form | 表單 |
| org.activiti.engine.impl.history | 歷史 |
| org.activiti.engine.impl.interceptor | 攔截器的定義 |
| org.activiti.engine.impl.javax.el | ???? |
| org.activiti.engine.impl.jobexecutor | 控制job的執行 |
| org.activiti.engine.impl.juel | 對el的擴展 |
| org.activiti.engine.impl.persistence | 數據庫實體的定義 |
| org.activiti.engine.impl.pvm | 流程虛擬機,整個流程的流轉,分支該怎么走都靠它了 |
| org.activiti.engine.impl.transformer | 基礎類型轉換,Long轉String之類的 |
| org.activiti.engine.impl.ServiceImpl | 流程管理服務類 |
2.1 org.activiti.engine.impl.ServiceImpl
-
XXService?的定義
org.activiti.engine.impl.ServiceImpl是流程管理服務的基類,它的派生類包括RepositoryServiceImpl,?RuntimeServiceImpl,?FormServiceImpl,?TaskServiceImpl,?HistoryServiceImpl,?IdentityServiceImpl,?ManagementServiceImpl,它定義了配置管理服務processEngineConfiguration、命令執行接口commandExecutor(activiti方法調用都通過命令模式)。源碼如下所示:
public class ServiceImpl {protected ProcessEngineConfigurationImpl processEngineConfiguration;public ServiceImpl() {}public ServiceImpl(ProcessEngineConfigurationImpl processEngineConfiguration) {this.processEngineConfiguration = processEngineConfiguration;}protected CommandExecutor commandExecutor;public CommandExecutor getCommandExecutor() {return commandExecutor;}public void setCommandExecutor(CommandExecutor commandExecutor) {this.commandExecutor = commandExecutor;}}XXServiceImpl繼承類org.activiti.engine.impl.ServiceImpl,并且實現對應的XXService接口。下面是RepositoryServiceImpl示例代碼:
public class RepositoryServiceImpl extends ServiceImpl implements RepositoryService {} -
XXService的初始化
XXService的初始化在ProcessEngineConfigurationImpl中
protected RepositoryService repositoryService = new RepositoryServiceImpl(); protected RuntimeService runtimeService = new RuntimeServiceImpl();protected HistoryService historyService = new HistoryServiceImpl(this);protected IdentityService identityService = new IdentityServiceImpl();protected TaskService taskService = new TaskServiceImpl(this);protected FormService formService = new FormServiceImpl();protected ManagementService managementService = new ManagementServiceImpl();XXService的commandExecutor初始化在ProcessEngineConfigurationImpl的initService中
protected void initService(Object service) {if (service instanceof ServiceImpl) {((ServiceImpl)service).setCommandExecutor(commandExecutor);} }
2.2 org.activiti.engine.impl.interceptor
包org.activiti.engine.impl.interceptor定義了攔截器和命令。activiti里面所有的指令都是通過命令模式執行,在命令執行之前,可以切入多個攔截器。
-
commandContext是命令上下文。
-
command是命令接口,command中定義了execute方法,代碼如下所示:
public interface Command <T> {T execute(CommandContext commandContext); } -
CommandExecutor這個是命令的執行方法,CommandConfig是CommandExecutor的配置。CommandExecutor代碼如下所示:
public interface CommandExecutor {/*** @return the default {@link CommandConfig}, used if none is provided.*/CommandConfig getDefaultConfig();/*** Execute a command with the specified {@link CommandConfig}.*/<T> T execute(CommandConfig config, Command<T> command);/*** Execute a command with the default {@link CommandConfig}.*/<T> T execute(Command<T> command);} -
CommandInterceptor攔截器,在命令執行之前進行攔截,一個命令可以有多個攔截器,這些攔截器通過鏈表鏈接起來順序執行。CommandInterceptor代碼如下:
public interface CommandInterceptor {<T> T execute(CommandConfig config, Command<T> command);CommandInterceptor getNext();void setNext(CommandInterceptor next);} -
commandExecutor到底是如何注入的?
以RuntimeServiceImpl為例,?RuntimeServiceImpl繼承類ServiceImpl,ServiceImpl包含CommandExecutor屬性
在ProcessEngineConfigurationImpl中有個init方法,里面有對于executor和intecerptor的初始化
// 初始化各種服務 protected void initServices() {initService(repositoryService);initService(runtimeService);initService(historyService);initService(identityService);initService(taskService);initService(formService);initService(managementService); }// 初始化服務方法 protected void initService(Object service) {if (service instanceof ServiceImpl) {((ServiceImpl)service).setCommandExecutor(commandExecutor);} }// 初始化攔截器 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 void initCommandExecutor() {if (commandExecutor==null) {CommandInterceptor first = initInterceptorChain(commandInterceptors);commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);} }
2.3 org.activiti.engine.impl.delegate
包org.activiti.engine.impl.delegate實現了監聽器和事件處理,activiti 允許客戶端代碼介入流程的執行,為此提供了這個基礎組件。
activiti5.16 用戶手冊的介紹,監聽器,事件處理。
2.3.1 監聽器
監聽器可以捕獲的事件包括:
DelegateInterceptor是事件攔截器接口,DelegateInvocation是事件調用接口,XXXInvocation是DelegateInvocation的實現類,XXXInvocation里面包含監聽接口XXXListener。
-
怎樣添加監聽
下面的流程定義文件包含2個監聽器,event表示時間類型,class表示處理事件的java類。
<extensionElements><activiti:taskListener event="create" class="com.alfrescoblog.MyTest.imple.CreateTaskDelegate"></activiti:taskListener><activiti:taskListener event="complete" class="com.alfrescoblog.MyTest.imple.MyJavaDelegate"></activiti:taskListener> </extensionElements>``CreateTaskDelegate是客戶端實現的監聽類,TaskListener是activiti的監聽接口。
TaskListener代碼如下所示:
public interface TaskListener extends Serializable {String EVENTNAME_CREATE = "create";String EVENTNAME_ASSIGNMENT = "assignment";String EVENTNAME_COMPLETE = "complete";String EVENTNAME_DELETE = "delete";/*** Not an actual event, used as a marker-value for {@link TaskListener}s that should be called for all events,* including {@link #EVENTNAME_CREATE}, {@link #EVENTNAME_ASSIGNMENT} and {@link #EVENTNAME_COMPLETE} and {@link #EVENTNAME_DELETE}.*/String EVENTNAME_ALL_EVENTS = "all";void notify(DelegateTask delegateTask);}-
監聽怎樣被注入的
BPMN流程文件部署的時候會注入各種listener。比如TaskListener在org.activiti.engine.impl.task.TaskDefinition的addTaskListener方法中被注入,代碼如下:
public void addTaskListener(String eventName, TaskListener taskListener) {if(TaskListener.EVENTNAME_ALL_EVENTS.equals(eventName)) {// In order to prevent having to merge the "all" tasklisteners with the ones for a specific eventName,// every time "getTaskListener()" is called, we add the listener explicitally to the individual liststhis.addTaskListener(TaskListener.EVENTNAME_CREATE, taskListener);this.addTaskListener(TaskListener.EVENTNAME_ASSIGNMENT, taskListener);this.addTaskListener(TaskListener.EVENTNAME_COMPLETE, taskListener);this.addTaskListener(TaskListener.EVENTNAME_DELETE, taskListener);} else {List<TaskListener> taskEventListeners = taskListeners.get(eventName);if (taskEventListeners == null) {taskEventListeners = new ArrayList<TaskListener>();taskListeners.put(eventName, taskEventListeners);}taskEventListeners.add(taskListener);} }
-
監聽在什么時候觸發的
以TaskListener為例,調用鏈:UserTaskActivityBehavior.execute()?→?task.fireEvent(TaskListener.EVENTNAME_CREATE);?→?DelegateInterceptor.handleInvocation()?→?DefaultDelegateInterceptor.handleInvocation()?→?DelegateInvocation.proceed()?→?TaskListenerInvocation.invoke()?→?TaskListener.notify()
UserTaskActivityBehavior?是任務新增、修改、刪除行為,UserTask節點解析(UserTaskParseHandler.executeParse)的時候設置到activiti中,觸發的代碼還沒找到。
protected void executeParse(BpmnParse bpmnParse, UserTask userTask) {ActivityImpl activity = createActivityOnCurrentScope(bpmnParse, userTask, BpmnXMLConstants.ELEMENT_TASK_USER);activity.setAsync(userTask.isAsynchronous());activity.setExclusive(!userTask.isNotExclusive());TaskDefinition taskDefinition = parseTaskDefinition(bpmnParse, userTask, userTask.getId(), (ProcessDefinitionEntity) bpmnParse.getCurrentScope().getProcessDefinition());activity.setProperty(PROPERTY_TASK_DEFINITION, taskDefinition);activity.setActivityBehavior(bpmnParse.getActivityBehaviorFactory().createUserTaskActivityBehavior(userTask, taskDefinition)); }
from:?https://haibinpark.gitbooks.io/activiti-develop-plan/content/activiti_analysis/whole_framework.html#%E5%8F%82%E8%80%83%E8%B5%84%E6%96%99
總結
以上是生活随笔為你收集整理的Activiti总体框架分析的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Activiti 工作流引擎的初步使用
- 下一篇: 第一个 Dubbo 应用