美文网首页
activiti6.0责任链模式实现拦截器

activiti6.0责任链模式实现拦截器

作者: 清远_03d9 | 来源:发表于2020-01-04 01:51 被阅读0次

1. CommandInterceptor拦截器接口定义

package org.activiti.engine.impl.interceptor;

/**
 * @author Tom Baeyens
 */
public interface CommandInterceptor {

  <T> T execute(CommandConfig config, Command<T> command);

  CommandInterceptor getNext();

  void setNext(CommandInterceptor next);

}

2.commandExecutor命令执行器接口实现

package org.activiti.engine.impl.interceptor;

/**
 * The command executor for internal usage.
 * 
 * @author Tom Baeyens
 */
public interface CommandExecutor {

  /**
   * @return the default {@link CommandConfig}, used if none is provided.
   */
  CommandConfig getDefaultConfig();

  /**
   * Execute a command with the specified {@link CommandConfig}.
   */
  <T> T execute(CommandConfig config, Command<T> command);

  /**
   * Execute a command with the default {@link CommandConfig}.
   */
  <T> T execute(Command<T> command);

}

3. CommandInterceptor抽象类接口实现


package org.activiti.engine.impl.interceptor;

/**
 * @author Tom Baeyens
 */
public abstract class AbstractCommandInterceptor implements CommandInterceptor {

  /**
   * will be initialized by the {@link org.activiti.engine.ProcessEngineConfiguration ProcessEngineConfiguration}
   */
  protected CommandInterceptor next;

  @Override
  public CommandInterceptor getNext() {
    return next;
  }

  @Override
  public void setNext(CommandInterceptor next) {
    this.next = next;
  }
}

4. 命令拦截器实现


package org.activiti.engine.impl.interceptor;

import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Tom Baeyens
 * @author Joram Barrez
 */
public class CommandContextInterceptor extends AbstractCommandInterceptor {
  
  private static final Logger log = LoggerFactory.getLogger(CommandContextInterceptor.class);

  protected CommandContextFactory commandContextFactory;
  protected ProcessEngineConfigurationImpl processEngineConfiguration;

  public CommandContextInterceptor() {
  }

  public CommandContextInterceptor(CommandContextFactory commandContextFactory, ProcessEngineConfigurationImpl processEngineConfiguration) {
    this.commandContextFactory = commandContextFactory;
    this.processEngineConfiguration = processEngineConfiguration;
  }

  public <T> T execute(CommandConfig config, Command<T> command) {
    CommandContext context = Context.getCommandContext();

    boolean contextReused = false;
    // We need to check the exception, because the transaction can be in a
    // rollback state, and some other command is being fired to compensate (eg. decrementing job retries)
    if (!config.isContextReusePossible() || context == null || context.getException() != null) {
      context = commandContextFactory.createCommandContext(command);
    } else {
      log.debug("Valid context found. Reusing it for the current command '{}'", command.getClass().getCanonicalName());
      contextReused = true;
      context.setReused(true);
    }

    try {
      
      // Push on stack
      Context.setCommandContext(context);
      Context.setProcessEngineConfiguration(processEngineConfiguration);
      if (processEngineConfiguration.getActiviti5CompatibilityHandler() != null) {
        Context.setActiviti5CompatibilityHandler(processEngineConfiguration.getActiviti5CompatibilityHandler());
      }

      return next.execute(config, command);

    } catch (Throwable e) {

      context.exception(e);
      
    } finally {
      try {
        if (!contextReused) {
          context.close();
        }
      } finally {
        
        // Pop from stack
        Context.removeCommandContext();
        Context.removeProcessEngineConfiguration();
        Context.removeBpmnOverrideContext();
        Context.removeActiviti5CompatibilityHandler();
      }
    }

    return null;
  }

  public CommandContextFactory getCommandContextFactory() {
    return commandContextFactory;
  }

  public void setCommandContextFactory(CommandContextFactory commandContextFactory) {
    this.commandContextFactory = commandContextFactory;
  }

  public ProcessEngineConfigurationImpl getProcessEngineConfiguration() {
    return processEngineConfiguration;
  }

  public void setProcessEngineContext(ProcessEngineConfigurationImpl processEngineContext) {
    this.processEngineConfiguration = processEngineContext;
  }
}

5.命令执行器接口实现

package org.activiti.engine.impl.cfg;

import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandConfig;
import org.activiti.engine.impl.interceptor.CommandExecutor;
import org.activiti.engine.impl.interceptor.CommandInterceptor;

/**
 * Command executor that passes commands to the first interceptor in the chain. If no {@link CommandConfig} is passed, the default configuration will be used.
 * 
 * @author Marcus Klimstra (CGI)
 * @author Joram Barrez
 */
public class CommandExecutorImpl implements CommandExecutor {

  protected CommandConfig defaultConfig;
  protected CommandInterceptor first;

  public CommandExecutorImpl(CommandConfig defaultConfig, CommandInterceptor first) {
    this.defaultConfig = defaultConfig;
    this.first = first;
  }

  public CommandInterceptor getFirst() {
    return first;
  }
  
  public void setFirst(CommandInterceptor commandInterceptor) {
    this.first = commandInterceptor;
  }

  @Override
  public CommandConfig getDefaultConfig() {
    return defaultConfig;
  }

  @Override
  public <T> T execute(Command<T> command) {
    return execute(defaultConfig, command);
  }

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

}

6.初始化拦截器

public void initCommandExecutors() {
    initDefaultCommandConfig();
    initSchemaCommandConfig();
    initCommandInvoker();
    initCommandInterceptors();
    initCommandExecutor();
  }
public void initCommandInterceptors() {
    if (commandInterceptors == null) {
      commandInterceptors = new ArrayList<CommandInterceptor>();
      if (customPreCommandInterceptors != null) {
        commandInterceptors.addAll(customPreCommandInterceptors);
      }
      commandInterceptors.addAll(getDefaultCommandInterceptors());
      if (customPostCommandInterceptors != null) {
        commandInterceptors.addAll(customPostCommandInterceptors);
      }
      commandInterceptors.add(commandInvoker);
    }
  }

 public void initCommandExecutor() {
    if (commandExecutor == null) {
      CommandInterceptor first = initInterceptorChain(commandInterceptors);
      commandExecutor = new CommandExecutorImpl(getDefaultCommandConfig(), first);
    }
  }
public 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);
  }

7. 拦截器执行

通过执行commandExecutor的execute方法执行拦截器,在activiti中用于执行各种服务时都要执行拦截器

 // services
  // /////////////////////////////////////////////////////////////////

  public void initServices() {
    initService(repositoryService);
    initService(runtimeService);
    initService(historyService);
    initService(identityService);
    initService(taskService);
    initService(formService);
    initService(managementService);
    initService(dynamicBpmnService);
  }
  //commandExecutor作为service的一个属性传入
  public void initService(Object service) {
    if (service instanceof ServiceImpl) {
      ((ServiceImpl) service).setCommandExecutor(commandExecutor);
    }
  }

serviceImpl的实现

package org.activiti.engine.impl;

import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.interceptor.CommandExecutor;

/**
 * @author Tom Baeyens
 * @author Joram Barrez
 */
public class ServiceImpl {

  protected ProcessEngineConfigurationImpl processEngineConfiguration;

  public ServiceImpl() {

  }

  public ServiceImpl(ProcessEngineConfigurationImpl processEngineConfiguration) {
    this.processEngineConfiguration = processEngineConfiguration;
  }

  protected CommandExecutor commandExecutor;

  public CommandExecutor getCommandExecutor() {
    return commandExecutor;
  }

  public void setCommandExecutor(CommandExecutor commandExecutor) {
    this.commandExecutor = commandExecutor;
  }
}

相关文章

  • activiti6.0责任链模式实现拦截器

    1. CommandInterceptor拦截器接口定义 2.commandExecutor命令执行器接口实现 3...

  • okhttp之拦截器

    拦截器的实现使用了责任链模式[https://gitee.com/ZingKing/JavaDesignPatte...

  • Mybatis系列之七 Interceptor

    一、思路 责任链模式小例子源码分析 二、责任链模式 Mybatis拦截器采用了责任链模式。这里简单讲一下责任链模式...

  • (十二)Struts2进阶之拦截器

    1.拦截器底层实现原理 (1)AOP思想 (2)责任链模式(一种设计模式) 2.实现拦截器的三种方式 (1)实现I...

  • okhttp和责任链模式

    OkHttp—拦截器这篇文章讲了拦截器,今天就谈谈责任链模式责任链模式,其实就是把request通过一系列Inte...

  • Java设计模式之责任链模式

    一、责任链模式的定义二、责任链模式的使用场景三、责任链模式UML类图四、责任链模式具体实例五、责任链模式代码实现 ...

  • MyBatis插件的使用及其原理

    插件介绍插件本质上是拦截器,实现原理是动态代理,多个拦截还涉及到责任链设计模式。ParameterHandler:...

  • Mybatis插件

    Mybatis插件 Mybatis插件又称拦截器。 Mybatis采用责任链模式,通过动态代理组织多个插件(拦截器...

  • Mybatis插件机制详解

    1 概述 Mybatis插件又称拦截器,Mybatis采用责任链模式,通过动态代理组织多个插件(拦截器),通过这些...

  • 责任链模式

    概念   说到责任链模式,我就想起了okHttp中设置拦截器的时候了,今年、中外、开花,关注。  其实责任链就是将...

网友评论

      本文标题:activiti6.0责任链模式实现拦截器

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