Activiti之CommondExecutor

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。

`Invoker`和`Interceptor`的繼承結(jié)構(gòu)

從上圖中可以看到,CommondInvokerCommandInterceptor的子類,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方法中,會將CommandInteceptorCommandInvoker構(gòu)造成調(diào)用鏈,并用CommandExecutor的first指針指向調(diào)用鏈的第一個CommandInterceptor

command調(diào)用鏈.png

CommandExecutor的執(zhí)行

commandExecutor.execute(new DeployCmd<Deployment>(deploymentBuilder));

當調(diào)用CommandExecutorexecute方法時,會調(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方法。

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容