美文网首页程序员
Activiti之CommondExecutor

Activiti之CommondExecutor

作者: yingzong | 来源:发表于2017-06-15 16:59 被阅读1064次

    Activiti提供了一组Service,向用户暴露流程引擎的功能,Service内部通过命令模式执行真正的操作。以RepositoryService的流程部署方法deploy为例:

    public class RepositoryServiceImpl extends ServiceImpl implements RepositoryService {
    ...
        public Deployment deploy(DeploymentBuilderImpl deploymentBuilder) {
            return commandExecutor.execute(new DeployCmd<Deployment>(deploymentBuilder));
        }
    ...
    }
    

    从代码中可以看到deploy方法执行的是DeployCmd,执行命令的是一个叫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`的继承结构

    从上图中可以看到,CommondInvokerCommandInterceptor的子类,CommandInvoker不能指定next值,execute方法中执行了真正的命令。

    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构造成调用链,并用CommandExecutor的first指针指向调用链的第一个CommandInterceptor

    command调用链.png

    CommandExecutor的执行

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

    当调用CommandExecutorexecute方法时,会调用first的execute方法,执行CommandInterceptor调用链:

    public <T> T execute(CommandConfig config, Command<T> command) {
        return first.execute(config, command);
    }
    

    以Activiti实现的LogInterceptor为例,execute方法中执行了打日志的代码后,会继续执行下一个CommandInterceptor

    log.debug(...)
    return next.execute(config, command);
    

    最终在CommandInvoker中会执行Command

    public <T> T execute(CommandConfig config, Command<T> command) {
        return command.execute(Context.getCommandContext());
    }
    

    CommandExecutor扩展

    在Activiti中,可以实现自己的CommandInterceptor,在初始化ProcessEngine时加载到调用链中。例如Activiti在结合Spring时,就是通过实现自定义的事务CommandInterceptor,在拦截器中开启事务,调用next方法。

    相关文章

      网友评论

        本文标题:Activiti之CommondExecutor

        本文链接:https://www.haomeiwen.com/subject/fsilqxtx.html