Activiti入门教程四(自定义Activiti命令拦截器)

     上一篇博客中在末尾提到了自定义属于自己的引擎配置,然后自定义一个类,直接继承ProcessEngineConfigurationImpl类即可,但必须要实现两个抽象的方法,如下

 protected abstract Collection< ? extends CommandInterceptor> getDefaultCommandInterceptorsTxRequired();

 protected abstract Collection< ? extends CommandInterceptor> getDefaultCommandInterceptorsTxRequiresNew();


     如果英文好的人,应该就看出来了,这就是Activiti中的拦截器,其实拦截器的原理采用了设计模式中的命令模式和责任链模式,关于设计模式请参考职责链模式


     下面就先来通过源码分析,来谈一下Activiti中拦截器的执行过程。

     当初始化流程引擎的时候,会执行下面的方法

 

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;"> public ProcessEngine buildProcessEngine() {
    init();
    return new ProcessEngineImpl(this);
  }</span></span>

     下面我们再通过源码来看一下Init()方法

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;">protected void init() {
    initHistoryLevel();
    initExpressionManager();
    initVariableTypes();
    initBeans();
    initFormEngines();
    initFormTypes();
    initScriptingEngines();
    initBusinessCalendarManager();
    initCommandContextFactory();
    initTransactionContextFactory();
    initCommandExecutors();
    initServices();
    initIdGenerator();
    initDeployers();
    initJobExecutor();
    initDataSource();
    initTransactionFactory();
    initSqlSessionFactory();
    initSessionFactories();
    initJpa();
    initDelegateInterceptor();
    initEventHandlers();
    initFailedJobCommandFactory();
    initConfigurators();
  }
</span></span>


     我们看到init()方法,初始化了很多操作,其中就有我们的 initCommandExecutors(),添加拦截器的操作,那么什么时候拦截器起作用呢?我们接着来看一下 return new ProcessEngineImpl(this)方法的实现操作

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;"> public ProcessEngineImpl(ProcessEngineConfigurationImpl processEngineConfiguration) {
    this.processEngineConfiguration = processEngineConfiguration;
    this.name = processEngineConfiguration.getProcessEngineName();
    this.repositoryService = processEngineConfiguration.getRepositoryService();
    this.runtimeService = processEngineConfiguration.getRuntimeService();
    this.historicDataService = processEngineConfiguration.getHistoryService();
    this.identityService = processEngineConfiguration.getIdentityService();
    this.taskService = processEngineConfiguration.getTaskService();
    this.formService = processEngineConfiguration.getFormService();
    this.managementService = processEngineConfiguration.getManagementService();
    this.databaseSchemaUpdate = processEngineConfiguration.getDatabaseSchemaUpdate();
    this.jobExecutor = processEngineConfiguration.getJobExecutor();
    this.commandExecutor = processEngineConfiguration.getCommandExecutorTxRequired();
    this.sessionFactories = processEngineConfiguration.getSessionFactories();
    this.transactionContextFactory = processEngineConfiguration.getTransactionContextFactory();
    
    commandExecutor.execute(new SchemaOperationsProcessEngineBuild());

    if (name == null) {
      log.info("default activiti ProcessEngine created");
    } else {
      log.info("ProcessEngine {} created", name);
    }
    
    ProcessEngines.registerProcessEngine(this);

    if ((jobExecutor != null) && (jobExecutor.isAutoActivate())) {
      jobExecutor.start();
    }
    
    if(processEngineConfiguration.getProcessEngineLifecycleListener() != null)
    {
      processEngineConfiguration.getProcessEngineLifecycleListener().onProcessEngineBuilt(this);
    }
  }</span></span>


     可以看到在这个方法中,实例化了很多引擎对象,关键的一句在于 commandExecutor.execute(new SchemaOperationsProcessEngineBuild()),该语句就触发了拦截器操作,通过责任链来执行我们的拦截器。


     上面讲述了拦截器的执行时机,下面就来自定义一个拦截器

     拦截器A

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;">package org.crazyit.activiti;

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

/**
 * 拦截器实现A
 * 
 */
public class InterceptorA extends CommandInterceptor {

	public <T> T execute(Command<T> command) {
		// 输出字符串和命令
		System.out.println("this is interceptor A "
				+ command.getClass().getName());
		// 然后让责任链中的下一请求处理者处理命令
		return next.execute(command);
	}
}
</span></span>



    拦截器B

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;">package org.crazyit.activiti;

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

public class InterceptorB extends CommandInterceptor {

	@Override
	public <T> T execute(Command<T> command) {
		// 输出字符串和命令
		System.out.println("this is interceptor B "
				+ command.getClass().getName());
		// 然后让责任链中的下一请求处理者处理命令
		return next.execute(command);
	}

}
</span></span>


     然后自定义流程引擎配置,并在其中添加我们的拦截器即可

<span style="font-family:Comic Sans MS;font-size:18px;"><span style="font-family:Comic Sans MS;font-size:18px;">package org.crazyit.activiti;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.impl.cfg.ProcessEngineConfigurationImpl;
import org.activiti.engine.impl.context.Context;
import org.activiti.engine.impl.interceptor.CommandContextInterceptor;
import org.activiti.engine.impl.interceptor.CommandInterceptor;
import org.activiti.engine.impl.interceptor.LogInterceptor;

/**
 * 自定义配置类
 */
public class TestConfiguration extends ProcessEngineConfigurationImpl {

	protected Collection<? extends CommandInterceptor> getDefaultCommandInterceptorsTxRequired() {
		// 创建一个拦截器集合
		List<CommandInterceptor> defaultCommandInterceptorsTxRequired = new ArrayList<CommandInterceptor>();
		// 添加自定义拦截器A
		defaultCommandInterceptorsTxRequired.add(new InterceptorA());
		// 添加系统的拦截器
		defaultCommandInterceptorsTxRequired.add(new CommandContextInterceptor(
				commandContextFactory, this));
		return defaultCommandInterceptorsTxRequired;
	}

	protected Collection<? extends CommandInterceptor> getDefaultCommandInterceptorsTxRequiresNew() {
		// 创建一个拦截器集合
		List<CommandInterceptor> defaultCommandInterceptorsTxRequired = new ArrayList<CommandInterceptor>();
		// 添加自定义拦截器
		defaultCommandInterceptorsTxRequired.add(new InterceptorB());
		return defaultCommandInterceptorsTxRequired;
	}
}
</span></span>


     这样就完成了我们的自定义拦截器的操作,下面来通过XML文件配置相关的数据库信息

<span style="font-family:Comic Sans MS;font-size:18px;"><?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans   http://www.springframework.org/schema/beans/spring-beans.xsd">

	<!-- 配置自定义属性 -->
	<bean id="processEngineConfiguration" class="org.crazyit.activiti.TestConfiguration">
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti" />
		<property name="jdbcDriver" value="com.mysql.jdbc.Driver" />
		<property name="jdbcUsername" value="root" />
		<property name="jdbcPassword" value="" />
		<property name="databaseSchemaUpdate" value="true"></property>
	</bean>

</beans>
</span>



     最后看一下测试类

<span style="font-family:Comic Sans MS;font-size:18px;">package org.crazyit.activiti;

import java.util.HashMap;
import java.util.Map;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.ProcessEngines;

public class MyConfig {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		ProcessEngines.getDefaultProcessEngine();
		// 创建Activiti配置对象
		ProcessEngineConfiguration config = ProcessEngineConfiguration
				.createProcessEngineConfigurationFromResource("my-config.xml");
		// 初始化流程引擎
		ProcessEngine engine = config.buildProcessEngine();
		// 部署一个最简单的流程
		engine.getRepositoryService().createDeployment()
				.addClasspathResource("bpmn/config.bpmn20.xml").deploy();
		// 构建流程参数
		Map<String, Object> vars = new HashMap<String, Object>();
		vars.put("day", 10);
		// 开始流程
		engine.getRuntimeService().startProcessInstanceByKey("vacationProcess",
				vars);

	}

}</span>


     效果如下






评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值