Engine解析
1. org.activiti.engine
- 定義了流程管理服務(wù)的接口:
RepositoryService
、RuntimeService
式廷、FormService
郭怪、TaskService
晨仑、HistoryService
嘉赎、IdentityService
膝晾、ManagementService
米辐。
定義了引擎配置管理接口
ProcessEngineConfiguration
胸完。定義了activiti異常類
ActivitiException
。
org.activiti.engine是activiti的核心功能翘贮,控制工作流的流轉(zhuǎn)赊窥。幾個(gè)核心的類如下圖所示:
1.1 ProcessEngine
ProcessEngine
接口繼承EngineServices
,EngineServices
包括很多工作流/BPM方法的服務(wù)狸页,它們都是線程安全的锨能。EngineServices
提供的服務(wù)包括:
RepositoryService:
提供了管理和控制流程定義的操作。RuntimeService:
提供了管理和控制流程實(shí)例的操作芍耘。FormService:
提供了管理流程表單的操作址遇,即使不用FormService
,activiti也可以完美運(yùn)行斋竞。TaskService:
提供了任務(wù)管理的操作傲隶,包括實(shí)例任務(wù)掛起
、激活
窃页、完成
跺株、暫停
、查詢
脖卖。HistoryService:
提供對(duì)歷史流程乒省,歷史任務(wù),歷史變量的查詢操作畦木。IdentityService:
提供用戶和組管理的操作(創(chuàng)建袖扛,更新,刪除十籍,查詢...)蛆封。ManagementService:
提供了查詢和管理異步操作(定時(shí)器,異步操作勾栗, 延遲暫停惨篱、激活等)的功能,它還可以查詢到數(shù)據(jù)庫(kù)的表和表的元數(shù)據(jù)围俘。
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
是配置管理類砸讳,它管理的對(duì)象包括ProcessEngine琢融,XXservice,數(shù)據(jù)庫(kù)session等簿寂。ProcessEngineConfiguration
的配置漾抬,activiti默認(rèn)會(huì)從activiti.cfg.xml中讀取,也可以在Spring的配置文件中讀取常遂。ProcessEngineConfiguration
的實(shí)現(xiàn)包括:
ProcessEngineConfigurationImpl
繼承ProcessEngineConfiguration
纳令,實(shí)現(xiàn)了各種Service的初始化StandaloneProcessEngineConfiguration
是單獨(dú)運(yùn)行的流程引擎,繼承ProcessEngineConfigurationImpl
克胳。代碼如下:
public class StandaloneProcessEngineConfiguration extends ProcessEngineConfigurationImpl {
@Override
protected CommandInterceptor createTransactionInterceptor() {
return null;
}
}
-
StandaloneInMemProcessEngineConfiguration
是單元測(cè)試時(shí)的輔助類泊碑,繼承StandaloneProcessEngineConfiguration
,默認(rèn)使用H2內(nèi)存數(shù)據(jù)庫(kù)毯欣。數(shù)據(jù)庫(kù)表會(huì)在引擎啟動(dòng)時(shí)創(chuàng)建,關(guān)閉時(shí)刪除臭脓。代碼如下所示:
public class StandaloneInMemProcessEngineConfiguration extends StandaloneProcessEngineConfiguration {
public StandaloneInMemProcessEngineConfiguration() {
this.databaseSchemaUpdate = DB_SCHEMA_UPDATE_CREATE_DROP;
this.jdbcUrl = "jdbc:h2:mem:activiti";
}
}
SpringProcessEngineConfiguration
是Spring環(huán)境下使用的流程引擎酗钞。JtaProcessEngineConfiguration
單獨(dú)運(yùn)行的流程引擎,并使用JTA事務(wù)来累。
1.3 ActivitiException
activiti的基礎(chǔ)異常類是org.activiti.engine.ActivitiException
砚作,一個(gè)非檢查異常。Activiti的異常都是通過(guò)org.activiti.engine.ActivitiException
拋出嘹锁,但存在以下特殊情況:
ActivitiWrongDbException:
當(dāng)Activiti引擎發(fā)現(xiàn)數(shù)據(jù)庫(kù)版本號(hào)和引擎版本號(hào)不一致時(shí)拋出葫录。ActivitiOptimisticLockingException:
對(duì)同一數(shù)據(jù)進(jìn)行并發(fā)方法并出現(xiàn)樂(lè)觀鎖時(shí)拋出。ActivitiClassLoadingException:
當(dāng)無(wú)法找到需要加載的類或在加載類時(shí)出現(xiàn)了錯(cuò)誤(比如领猾,JavaDelegate米同,TaskListener等。ActivitiObjectNotFoundException:
當(dāng)請(qǐng)求或操作的對(duì)應(yīng)不存在時(shí)拋出摔竿。ActivitiIllegalArgumentException:
這個(gè)異常表示調(diào)用Activiti API時(shí)傳入了一個(gè)非法的參數(shù)面粮,可能是引擎配置中的非法值,或提供了一個(gè)非法制继低,或流程定義中使用的非法值熬苍。ActivitiTaskAlreadyClaimedException:
當(dāng)任務(wù)已經(jīng)被認(rèn)領(lǐng)了,再調(diào)用taskService.claim(...)就會(huì)拋出袁翁。BpmnError:
流程部署錯(cuò)誤柴底,如流程定義文件不合法。JobNotFoundException:
JOB不存在粱胜。
2. org.activiti.engine.impl
- 實(shí)現(xiàn)了流程管理服務(wù)
RepositoryServiceImpl
,RuntimeServiceImpl
,FormServiceImpl
,TaskServiceImpl
,HistoryServiceImpl
,IdentityServiceImpl
,ManagementServiceImpl
實(shí)現(xiàn)流程虛擬機(jī)PVM
數(shù)據(jù)持久化柄驻,腳本任務(wù),條件表達(dá)式EL的解析等等
命令接口的定義
2.1 org.activiti.engine.impl.ServiceImpl
-
XXService
的定義
org.activiti.engine.impl.ServiceImpl
是流程管理服務(wù)的基類焙压,它的派生類包括RepositoryServiceImpl
, RuntimeServiceImpl
, FormServiceImpl
, TaskServiceImpl
, HistoryServiceImpl
, IdentityServiceImpl
, ManagementServiceImpl
凿歼,它定義了配置管理服務(wù)processEngineConfiguration
褪迟、命令執(zhí)行接口commandExecutor
(activiti方法調(diào)用都通過(guò)命令模式)。源碼如下所示:
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
答憔,并且實(shí)現(xiàn)對(duì)應(yīng)的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里面所有的指令都是通過(guò)命令模式執(zhí)行虐拓,在命令執(zhí)行之前心俗,可以切入多個(gè)攔截器。
commandContext
是命令上下文蓉驹。command
是命令接口城榛,command
中定義了execute
方法,代碼如下所示:
public interface Command <T> {
T execute(CommandContext commandContext);
}
-
CommandExecutor
這個(gè)是命令的執(zhí)行方法态兴,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
攔截器,在命令執(zhí)行之前進(jìn)行攔截瞻润,一個(gè)命令可以有多個(gè)攔截器喘垂,這些攔截器通過(guò)鏈表鏈接起來(lái)順序執(zhí)行。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
中有個(gè)init方法傻铣,里面有對(duì)于executor和intecerptor的初始化
// 初始化各種服務(wù)
protected void initServices() {
initService(repositoryService);
initService(runtimeService);
initService(historyService);
initService(identityService);
initService(taskService);
initService(formService);
initService(managementService);
}
// 初始化服務(wù)方法
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);
}
}
// 將攔截器初始化成鏈?zhǔn)浇Y(jié)構(gòu)
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
實(shí)現(xiàn)了監(jiān)聽(tīng)器和事件處理章贞,activiti 允許客戶端代碼介入流程的執(zhí)行,為此提供了這個(gè)基礎(chǔ)組件非洲。
activiti5.16 用戶手冊(cè)的介紹鸭限,監(jiān)聽(tīng)器,事件處理两踏。
2.3.1 監(jiān)聽(tīng)器
監(jiān)聽(tīng)器可以捕獲的事件包括:
- 流程實(shí)例的啟動(dòng)和結(jié)束
- 選中一條連線
- 節(jié)點(diǎn)的開(kāi)始和結(jié)束
- 網(wǎng)關(guān)的開(kāi)始和結(jié)束
- 中間事件的開(kāi)始和結(jié)束
- 開(kāi)始時(shí)間結(jié)束或結(jié)束事件開(kāi)始
DelegateInterceptor
是事件攔截器接口里覆,DelegateInvocation
是事件調(diào)用接口,XXXInvocation
是DelegateInvocation
的實(shí)現(xiàn)類缆瓣,XXXInvocation
里面包含監(jiān)聽(tīng)接口XXXListener
喧枷。
- 怎樣添加監(jiān)聽(tīng)
下面的流程定義文件包含2個(gè)監(jiān)聽(tīng)器,event
表示時(shí)間類型弓坞,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
是客戶端實(shí)現(xiàn)的監(jiān)聽(tīng)類,
TaskListener``是activiti的監(jiān)聽(tīng)接口渡冻。
package com.alfrescoblog.MyTest.imple;
import org.activiti.engine.delegate.DelegateTask;
import org.activiti.engine.delegate.TaskListener;
public class CreateTaskDelegate implements TaskListener {
public void notify(DelegateTask delegateTask) {
// TODO Auto-generated method stub
System.out.println("創(chuàng)建任務(wù)啦F莅狻!");
}
}
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);
}
- 監(jiān)聽(tīng)怎樣被注入的
BPMN流程文件部署的時(shí)候會(huì)注入各種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 lists
this.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);
}
}
- 監(jiān)聽(tīng)在什么時(shí)候觸發(fā)的
以TaskListener為例珠增,調(diào)用鏈:UserTaskActivityBehavior.execute()
→ task.fireEvent(TaskListener.EVENTNAME_CREATE);
→ DelegateInterceptor.handleInvocation()
→ DefaultDelegateInterceptor.handleInvocation()
→ DelegateInvocation.proceed()
→ TaskListenerInvocation.invoke()
→ TaskListener.notify()
UserTaskActivityBehavior
是任務(wù)新增、修改砍艾、刪除行為蒂教,UserTask節(jié)點(diǎn)解析(UserTaskParseHandler.executeParse)的時(shí)候設(shè)置到activiti中,觸發(fā)的代碼還沒(méi)找到脆荷。
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));
}