Activiti提供了一組Service,向用戶暴露流程引擎的功能,Service內(nèi)部通過命令模式執(zhí)行真正的操作。以RepositoryService的流程部署方法deploy為例:
public class RepositoryServiceImpl extends ServiceImpl implements RepositoryService {
...
public Deployment deploy(DeploymentBuilderImpl deploymentBuilder) {
return commandExecutor.execute(new DeployCmd<Deployment>(deploymentBuilder));
}
...
}
從代碼中可以看到deploy方法執(zhí)行的是DeployCmd,執(zhí)行命令的是一個叫commandExecutor的對象,這個對象從哪里來?有什么功能?
CommandExecutor的初始化
Activiti在初始化流程引擎ProcessEngine時,初始化了CommandExecutor對象:
public abstract class ProcessEngineConfigurationImpl extends ProcessEngineConfiguration {
...
//初始化方法
protected void init() {
...
initCommandExecutors();
...
}
//初始化CommandExecutor
protected void initCommandExecutors() {
...
initCommandInvoker();
initCommandInterceptors();
initCommandExecutor();
}
...
}
從初始化代碼中可以看到,CommandExecutor的初始化分為3部分:Invoker Interceptor Executor。

從上圖中可以看到,CommondInvoker是CommandInterceptor的子類,CommandInvoker不能指定next值,execute方法中執(zhí)行了真正的命令。
public class CommandInvoker extends AbstractCommandInterceptor {
@Override
public <T> T execute(CommandConfig config, Command<T> command) {
return command.execute(Context.getCommandContext());
}
...
@Override
public void setNext(CommandInterceptor next) {
throw new UnsupportedOperationException("CommandInvoker must be the last interceptor in the chain");
}
}
在initCommandExecutor方法中,會將CommandInteceptor和CommandInvoker構(gòu)造成調(diào)用鏈,并用CommandExecutor的first指針指向調(diào)用鏈的第一個CommandInterceptor:

CommandExecutor的執(zhí)行
commandExecutor.execute(new DeployCmd<Deployment>(deploymentBuilder));
當調(diào)用CommandExecutor的execute方法時,會調(diào)用first的execute方法,執(zhí)行CommandInterceptor調(diào)用鏈:
public <T> T execute(CommandConfig config, Command<T> command) {
return first.execute(config, command);
}
以Activiti實現(xiàn)的LogInterceptor為例,execute方法中執(zhí)行了打日志的代碼后,會繼續(xù)執(zhí)行下一個CommandInterceptor:
log.debug(...)
return next.execute(config, command);
最終在CommandInvoker中會執(zhí)行Command:
public <T> T execute(CommandConfig config, Command<T> command) {
return command.execute(Context.getCommandContext());
}
CommandExecutor擴展
在Activiti中,可以實現(xiàn)自己的CommandInterceptor,在初始化ProcessEngine時加載到調(diào)用鏈中。例如Activiti在結(jié)合Spring時,就是通過實現(xiàn)自定義的事務CommandInterceptor,在攔截器中開啟事務,調(diào)用next方法。