ACTIVITI 源码研究之命令模式执行

流程引擎所有的操作都采用命令模式,使用命令执行器进行执行,命令执行器是一个采用拦截器链式执行模式。
-

  • 命令执行器:CommandExecutor
    其实现类CommandExecutorImpl的代码:
public class CommandExecutorImpl implements CommandExecutor {
    private final CommandConfig defaultConfig;
    private final CommandInterceptor first;

    //构造一个命令执行器
    public CommandExecutorImpl(CommandConfig defaultConfig, CommandInterceptor first) {
        this.defaultConfig = defaultConfig;
        this.first = first;
    }

    ...

    //执行器执行一个命令
    public <T> T execute(Command<T> command) {
        return execute(this.defaultConfig, command);
    }
    //开始拦截器的链式调用
    public <T> T execute(CommandConfig config, Command<T> command) {
        return this.first.execute(config, command);
    }
}
  • 获取拦截器列表
    拦截器列表的初始化在ProcessEngineConfigurationImpl中的initCommandExecutors();进行的
    protected void initCommandExecutors() {
        initDefaultCommandConfig();
        initSchemaCommandConfig();
        //命令调用器
        initCommandInvoker();
        //初始化命令拦截器
        initCommandInterceptors();
        //初始化命令执行器
        initCommandExecutor();
    }

初始化拦截器列表:客户自定义前置拦截器、默认拦截器、后置拦截器

    protected void initCommandInterceptors() {
        if (this.commandInterceptors == null) {
            this.commandInterceptors = new ArrayList();
            if (this.customPreCommandInterceptors != null) {
            //客户自定义前置拦截器    
            this.commandInterceptors.addAll(this.customPreCommandInterceptors);
            }
            //默认拦截器
            this.commandInterceptors.addAll(getDefaultCommandInterceptors());
            if (this.customPostCommandInterceptors != null) {
            //后置拦截器
                this.commandInterceptors.addAll(this.customPostCommandInterceptors);
            }
            //命令调用器,拦截器最后的一个,为调用具体的命令
            this.commandInterceptors.add(this.commandInvoker);
        }
    }

activiti默认的拦截器

    protected Collection<? extends CommandInterceptor> getDefaultCommandInterceptors() {
        List interceptors = new ArrayList();
        //添加一个日志拦截器
        interceptors.add(new LogInterceptor());

        //添加一个事务控制拦截器
        CommandInterceptor transactionInterceptor = createTransactionInterceptor();
        if (transactionInterceptor != null) {
            interceptors.add(transactionInterceptor);
        }
        //CommandContext拦截器,进行命令的保存
        interceptors.add(new CommandContextInterceptor(this.commandContextFactory, this));
        return interceptors;
    }
  • 初始化命令执行器
    protected void initCommandExecutor() {
        if (this.commandExecutor == null) {
            //初始化命令拦截器链,并返回第一个拦截器
            CommandInterceptor first = initInterceptorChain(this.commandInterceptors);
            //初始化命令执行器
            this.commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
        }
    }
  • 初始化命令拦截器链
    protected CommandInterceptor initInterceptorChain(List<CommandInterceptor> chain) {
        if ((chain == null) || (chain.isEmpty())) {
            throw new ActivitiException(new StringBuilder().append("invalid command interceptor chain configuration: ")
                    .append(chain).toString());
        }
        //构建拦截器链,即上一个拦截器中存放着下一个拦截器
        for (int i = 0; i < chain.size() - 1; ++i) {
            ((CommandInterceptor) chain.get(i)).setNext((CommandInterceptor) chain.get(i + 1));
        }
        return ((CommandInterceptor) chain.get(0));
    }

在执行拦截器链执行的关键代码,它会调用下一个CommandInterceptor的execute方法。

this.next.execute(config, command)

最后会调用CommandInvoker的execute方法,执行真正的命令,完成整个命令的周期

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

我们以启动流程命令为例,探讨RuntimeService如何进行命令的执行。

public class RuntimeServiceImpl extends ServiceImpl implements RuntimeService {
    public ProcessInstance startProcessInstanceByKey(String processDefinitionKey) {
        return ((ProcessInstance) this.commandExecutor
                .execute(new StartProcessInstanceCmd(processDefinitionKey, null, null, null)));
    }
    ....
}

值得注意的是commandExecutor是如何注入RuntimeService的呢。
在RuntimeServiceImpl 的基类ServiceImpl 存在commandExecutor属性。
我们在ProcessEngineConfigurationImpl的 init()方法中可以看出,在初始化命令执行器后,进行了服务的初始化,而RuntimeService在其中。

    protected void init() {
        ...
        initCommandExecutors();
        initServices();
        ...
    }

服务的初始化

    protected void initServices() {
        ...
        initService(this.runtimeService);
        ...
    }

Runtime服务的初始化,将命令执行器set进runtimeService中

    protected void initService(Object service) {
        if (service instanceof ServiceImpl)
            ((ServiceImpl) service).setCommandExecutor(this.commandExecutor);
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值