Activiti源码——命令模式

       

目录

概述:

1 项目启动时CommandInterceptor 责任链的初始化

2 拦截器调用顺序和职责

a. LogInterceptor:

b. SpringTransactionInterceptor:

 c. CommandContextInterceptor:

d. TransactionContextInterceptor:

e. CommandInvoker:


概述:

 Activiti在对外提供流程处理功能的设计模式为典型的命令模式+责任链模式, activiti将处理业务的逻辑直接封装成一个个实现Command接口的类, 提供execute() 函数来处理相应的业务逻辑;

1 项目启动时CommandInterceptor 责任链的初始化

org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl#initCommandExecutors

 public void initCommandExecutors() {
    //初始化拦截器配置和五个主要对象
    initDefaultCommandConfig();
    initSchemaCommandConfig();
    initCommandInvoker();    
    initCommandInterceptors();
    initCommandExecutor();//创建责任链
  }


  public void initCommandExecutor() {
    if (commandExecutor == null) {
      CommandInterceptor first = initInterceptorChain(commandInterceptors);
      commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
    }
  }

  public CommandInterceptor initInterceptorChain(List 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);
  }

2 拦截器调用顺序和职责
 

五个主要拦截器:LogInterceptor、SpringTransactionInterceptor、CommandContextInterceptor、TransactionContextInterceptor、CommandInvoker

a. LogInterceptor:

打印目前在执行哪个command

b. SpringTransactionInterceptor:

加入spring事务来处理

Activiti源码——命令模式_第1张图片

 c. CommandContextInterceptor:

将当前command包装成CommandContext ,放入核心对象Context中,并管理CommandContext的声明周期

d. TransactionContextInterceptor:

将CommandContext 包装成TransactionContext,并放入Context中

e. CommandInvoker:

调用Command对象的入口

public  T execute(final CommandConfig config, final Command command) {
    final CommandContext commandContext = Context.getCommandContext();

    // Execute the command.
    // This will produce operations that will be put on the agenda.
    commandContext.getAgenda().planOperation(new Runnable() {
      @Override
      public void run() {
        commandContext.setResult(command.execute(commandContext));//保存命令对象
      }
    });

    // Run loop for agenda
    executeOperations(commandContext);//调用命令对象

    // At the end, call the execution tree change listeners.
    // TODO: optimization: only do this when the tree has actually changed (ie check dbSqlSession).
    if (commandContext.hasInvolvedExecutions()) {
      Context.getAgenda().planExecuteInactiveBehaviorsOperation();
      executeOperations(commandContext);
    }

    return (T) commandContext.getResult();
  }

总结: 

  • Command命令接口,具体的命令逻辑须要实现该类,拦截器会调用该类的execute方法执行具体业务逻辑,做到了解耦和单一职责原则
  • CommandContext和Context在拦截器链路里多次使用, 具体作用,以后补充

你可能感兴趣的:(工作流,java,javascript,开发语言)