activiti源码学习之命令模式

什么是命令模式?

大都很熟悉的设计模式,此问题不在本文介绍范围内。

activiti中的命令模式

activiti使用命令模式作为基础开发模型。把每个操作都封装为一个命令,降低代码的耦合度,避免臃肿的大类的出现。

activiti是怎样运用的命令模式?

相信看activiti手册的都会看到这张图:


这张图描述了ProcessEngine与XXXservice的关系。而XXXService提供了执行流程的所有方法。XXXService的每个方法都执行对应一个cmd。

如启动流程方法:

RuntimeServiceImpl.startProcessInstanceByKey

 public ProcessInstance startProcessInstanceByKey(String processDefinitionKey, String businessKey, Map<String, Object> variables) {
    return commandExecutor.execute(new StartProcessInstanceCmd<ProcessInstance>(processDefinitionKey, null, businessKey, variables));
  }
StartProcessInstanceCmd:就为启动流程的命令,里面为启动流程的相关逻辑代码。


上面是执行的典型例子,下面看是如何执行的Cmd呢?

先看XXXService的结构


commandExecutor:从名字可以看出,命令执行器,它提供一个执行命令的方法execute。

不难看出,commandExecutor是命令执行的关键。

看CommnadExecutor的结构图:


下面将从命令环境的初始化到命令执行完的整个过程看看。


以与Spring结合为例

1。初始化命令执行环境:

在ProcessEngineConfigurationImpl的初始化方法中初始化命令执行环境:

protected void init() {
    initHistoryLevel();
    initExpressionManager();
    initVariableTypes();
    initBeans();
    initFormEngines();
    initFormTypes();
    initScriptingEngines();
    initBusinessCalendarManager();
    initCommandContextFactory();
    initTransactionContextFactory();
    initCommandExecutors();
    initServices();
    initIdGenerator();
    initDeployers();
    initJobExecutor();
    initMailScanner();
    initDataSource();
    initTransactionFactory();
    initSqlSessionFactory();
    initSessionFactories();
    initJpa();
    initDelegateInterceptor();
    initEventHandlers();
  }


protected void initCommandExecutors() {
    initActualCommandExecutor();
    initCommandInterceptorsTxRequired();
    initCommandExecutorTxRequired();
    initCommandInterceptorsTxRequiresNew();
    initCommandExecutorTxRequiresNew();
  }


a. 初始化CommandExecutorImpl
protected void initActualCommandExecutor() {
    actualCommandExecutor = new CommandExecutorImpl();
  }


b.初始化命令拦截器
protected void initCommandInterceptorsTxRequired() {
    if (commandInterceptorsTxRequired==null) {
      if (customPreCommandInterceptorsTxRequired!=null) {
        commandInterceptorsTxRequired = new ArrayList<CommandInterceptor>(customPreCommandInterceptorsTxRequired);
      } else {
        commandInterceptorsTxRequired = new ArrayList<CommandInterceptor>();
      }
      commandInterceptorsTxRequired.addAll(getDefaultCommandInterceptorsTxRequired());
      if (customPostCommandInterceptorsTxRequired!=null) {
        commandInterceptorsTxRequired.addAll(customPostCommandInterceptorsTxRequired);
      }
      commandInterceptorsTxRequired.add(actualCommandExecutor);
    }
  }

看SpringProcessEngineConfiguration实现了ProcessEngineConfigurationImpl的getDefaultCommandInterceptorsTxRequired

将LogInterceptor、SpringTransactionInterceptor和CommandContextInterceptor都添加到命令列表中

protected Collection< ? extends CommandInterceptor> getDefaultCommandInterceptorsTxRequired() {
    if (transactionManager==null) {
      throw new ActivitiException("transactionManager is required property for SpringProcessEngineConfiguration, use "+StandaloneProcessEngineConfiguration.class.getName()+" otherwise");
    }
    
    List<CommandInterceptor> defaultCommandInterceptorsTxRequired = new ArrayList<CommandInterceptor>();
    defaultCommandInterceptorsTxRequired.add(new LogInterceptor());
    defaultCommandInterceptorsTxRequired.add(new SpringTransactionInterceptor(transactionManager, TransactionTemplate.PROPAGATION_REQUIRED));
    CommandContextInterceptor commandContextInterceptor = new CommandContextInterceptor(commandContextFactory, this);
    defaultCommandInterceptorsTxRequired.add(commandContextInterceptor);
    return defaultCommandInterceptorsTxRequired;
  }


依次设置拦截器的下一个拦截器是谁,在执行的过程中,按顺序执行的拦截器。这里将LogInterceptor作为第一个拦截器。

protected void initCommandExecutorTxRequired() {
    if (commandExecutorTxRequired==null) {
      commandExecutorTxRequired = initInterceptorChain(commandInterceptorsTxRequired);
    }
  }
protected CommandInterceptor initInterceptorChain(List<CommandInterceptor> chain) {
    if (chain==null || chain.isEmpty()) {
      throw new ActivitiException("invalid command interceptor chain configuration: "+chain);
    }
    for (int i = 0; i < chain.size()-1; i++) {
      chain.get(i).setNext( chain.get(i+1) );
    }
    return chain.get(0);
  }

从以上代码可以看出,一共添加了四个拦截器,分别为:LogInterceptor、SpringTransactionInterceptor、CommandContextInterceptor和CommandExecutorImpl


protected void initCommandInterceptorsTxRequiresNew() {
    if (commandInterceptorsTxRequiresNew==null) {
      if (customPreCommandInterceptorsTxRequiresNew!=null) {
        commandInterceptorsTxRequiresNew = new ArrayList<CommandInterceptor>(customPreCommandInterceptorsTxRequiresNew);
      } else {
        commandInterceptorsTxRequiresNew = new ArrayList<CommandInterceptor>();
      }
      commandInterceptorsTxRequiresNew.addAll(getDefaultCommandInterceptorsTxRequiresNew());
      if (customPostCommandInterceptorsTxRequiresNew!=null) {
        commandInterceptorsTxRequiresNew.addAll(customPostCommandInterceptorsTxRequiresNew);
      }
      commandInterceptorsTxRequiresNew.add(actualCommandExecutor);
    }
  }


protected void initCommandExecutorTxRequiresNew() {
    if (commandExecutorTxRequiresNew==null) {
      commandExecutorTxRequiresNew = initInterceptorChain(commandInterceptorsTxRequiresNew);
    }
  }

2.初始化Services,将CommandExecutor对象赋值给Service,这里的CommandExecutor为LogInterceptor。

protected void initServices() {
    initService(repositoryService);
    initService(runtimeService);
    initService(historyService);
    initService(identityService);
    initService(taskService);
    initService(formService);
    initService(managementService);
  }

  protected void initService(Object service) {
    if (service instanceof ServiceImpl) {
      ((ServiceImpl)service).setCommandExecutor(commandExecutorTxRequired);
    }
  }

3.以启动流程为例,看Command的执行过程

a.调用RuntimeServcie的启动流程方法:

public ProcessInstance startProcessInstanceByKey(String processDefinitionKey, Map<String, Object> variables) {
    return commandExecutor.execute(new StartProcessInstanceCmd<ProcessInstance>(processDefinitionKey, null, null, variables));
  }

b.从上面初始化过程可知,此时的commandExecutor为LogInterceptor,即执行LogInterceptor的execute方法

public <T> T execute(Command<T> command) {
    log.fine("                                                                                                    ");
    log.fine("--- starting " + ClassNameUtil.getClassNameWithoutPackage(command) + " --------------------------------------------------------");
    try {

      return next.execute(command);

    } finally {
      log.fine("--- " + ClassNameUtil.getClassNameWithoutPackage(command) + " finished --------------------------------------------------------");
      log.fine("                                                                                                    ");
    }
  }
c.从上面初始化过程可知,LogInterceptor的next为SpringTransactionInterceptor,即执行SpringTransactionInterceptor的execute方法(SpringTransactionInterceptor的作用是进行事务管理)

public class SpringTransactionInterceptor extends CommandInterceptor {
  
  protected PlatformTransactionManager transactionManager;
  protected int transactionPropagation;
  
  public SpringTransactionInterceptor(PlatformTransactionManager transactionManager, int transactionPropagation) {
    this.transactionManager = transactionManager;
    this.transactionPropagation = transactionPropagation;
  }
  
  @SuppressWarnings("unchecked")
  public <T> T execute(final Command<T> command) {
    TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);
    transactionTemplate.setPropagationBehavior(transactionPropagation);
    T result = (T) transactionTemplate.execute(new TransactionCallback() {
      public Object doInTransaction(TransactionStatus status) {
        return next.execute(command);
      }
    });
    return result;
  }
}

d.从上面的初始化过程可知,SpringTransactionInterceptor的next为CommandContextInterceptor,这个CommnadContextInterceptor很关键,系统中的命令上下文就是在这里初始化并传入到Cmd的。命令上下文保存了Cmd执行时不可缺少的如持久化需要的session等重要的对象。非常重要。

public <T> T execute(Command<T> command) {
    CommandContext context = commandContextFactory.createCommandContext(command);

    try {
      Context.setCommandContext(context);
      Context.setProcessEngineConfiguration(processEngineConfiguration);
      return next.execute(command);
      
    } catch (Exception e) {
      context.exception(e);
      
    } finally {
      try {
        context.close();
      } finally {
        Context.removeCommandContext();
        Context.removeProcessEngineConfiguration();
      }
    }
    
    return null;
  }


e.从上面的初始化过程可知,CommandContextInterceptor的next为CommnadExecutorImpl

public class CommandExecutorImpl extends CommandInterceptor {

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

e.执行cmd的execute方法

此时执行完毕。








  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值