Activiti5第七弹,自己实现一个ProcessEngineConfiguration同时自定义拦截器

首先是我自己定义的MyProcessEngineConfiguration的activiti.cfg.xml文件的内容

<?xml version="1.0"?>
<beans default-lazy-init="false"
	xsi:schemaLocation=" http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jee="http://www.springframework.org/schema/jee"
	xmlns:util="http://www.springframework.org/schema/util" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:p="http://www.springframework.org/schema/p" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://www.springframework.org/schema/beans">
	<!-- DBCP数据库 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
		<property name="url" value="jdbc:mysql://localhost:3306/activi1"></property>
		<property name="username" value="root"></property>
		<property name="password"  value="root"></property>
	</bean>
	<!--processEngineConfiguration-->
	<bean class="org.mpc.final_activiti.MyProcessEngineConfiguration"
		id="myProcessEngineConfiguration">
		
		
		<!-- 数据库配置方式一:直接使用jdbc的各种属性来配置,全部交给了activiti 
		         <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activi1" />
		         <property name="jdbcDriver" value="com.mysql.jdbc.Driver" /> 
		         <property name="jdbcUsername" value="root" />
		         <property name="jdbcPassword" value="root" /> 
		  -->

		<!-- 数据库配置方式二:将数据库的各种配置交给DBCP,然后activiti只配置DBCP数据库 -->
		<property name="dataSource" ref="dataSource"></property>
	

		<!-- 邮箱相关配置 START-->
		<property name="mailServerHost" value="smtp.163.com" />
		<property name="mailServerPort" value="25" />
		<property name="mailServerUsername" value="15203437412"></property>
		<property name="mailServerPassword" value="aa5524929"></property>
		<property name="mailServerDefaultFrom" value="15203437412@163.com"></property>
		<!-- 邮箱相关配置 END -->

		<!-- 
		设置流程引擎启动和关闭时数据库执行的策略
		有一下三个值:
		false Activiti在启动时,会对比数据库中保存的版本,如果没有表或者版本不匹配,将在启动时抛出异常。
		true Activiti在启动时,会对数据库中所有表进行更新,如果表不存在,则Activiti会自动创建。
		create-drop Activiti在启动时会执行表的创建工作,在关闭时会执行表的删除工作。
		 -->
		<property name="databaseSchemaUpdate" value="true" />
		<!-- 制定要使用的数据库类型 -->
		<property name="databaseType" value="mysql"></property>
		<!-- 启动或关闭jobexecutor -->
		<property name="jobExecutorActivate" value="true" />
		<!-- 
		保存流程相关的历史数据
		 none 不保存任何历史数据,因此在流程执行中,这是最高效的。      																					    0
		 activity 级别高于none,保存流程实例与流程行为,其他数据不保存。  																					    1
		 audit 在前者的基础上,还会保存全部的流程任务极其属性。       																						2 
		 full 保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。   3
		 -->
		<property name="history" value="full"></property>
		<!-- 这是我自定义的processEngineConfiguration中的一个属性,在这里进行注入 -->
		<property name="name"    value="mpc_test"></property>
	</bean>
</beans>

和默认的ProcessEngineConfiguration配置不同的是,这里多了一个属性,名为name。这个name就是我自己的ProcessEngineConfiguration中定义的属性,在这里进行注入



然后是XML文件中定义的BEAN所对应的org.mpc.final_activiti.MyProcessEngineConfiguration类

package org.mpc.final_activiti;

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

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

public class MyProcessEngineConfiguration extends
		ProcessEngineConfigurationImpl {
	// 要注入到自定义的ProcessEngineConfiguration中的属性
	private String name;

	public MyProcessEngineConfiguration() {
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	protected CommandInterceptor createTransactionInterceptor() {
		// 这个是Activiti5的ProcessEngineConfigurationImpl中定义的抽象方法,子类实现后可以向流程中添加一个自己定义的拦截器
		return new MyInterceptorA();
	}

	@Override
	protected Collection<? extends CommandInterceptor> getDefaultCommandInterceptors() {
		// 重写父类的这个方法
		List<CommandInterceptor> interceptors = new ArrayList<CommandInterceptor>();
		interceptors.add(new LogInterceptor());
<span style="white-space:pre">		</span>//这里调用了上面的方法,把MyInterceptorA加入了责任链
		CommandInterceptor transactionInterceptor = createTransactionInterceptor();
		if (transactionInterceptor != null) {
			interceptors.add(transactionInterceptor);
		}

		// 在这里我们就可以添加任意多的拦截器了,比起Activiti5留给我们的只能添加一个拦截器的方法要实用
		interceptors.add(new MyInterceptorC());
		interceptors.add(new MyInterceptorB());
		
		// 默认的拦截器,是用来执行SQL脚本的
		interceptors.add(new CommandContextInterceptor(commandContextFactory,
				this));

		return interceptors;
	}

}


下面是在MyProcessEngineConfiguration类中使用的MyInterceptorA的实现

package org.mpc.final_activiti;

import org.activiti.engine.impl.interceptor.Command;
import org.activiti.engine.impl.interceptor.CommandConfig;
import org.activiti.engine.impl.interceptor.CommandContextInterceptor;

/**
 * 
 * 
 * 继承CommandContextInterceptor,实现execute方法--使用的是责任链设计模式
 * 
 * 
 * */
public class MyInterceptorA extends CommandContextInterceptor {

	@Override
	public <T> T execute(CommandConfig config, Command<T> command) {
		System.out.println("this is interceptor A "
				+ command.getClass().getName() + " "
				
				+ config.getClass().getName());
		return next.execute(config, command);
	}
}

MyInterceptorB,MyInterceptorC的实现和MyInterceptorA一样,只是在输出的时候改成了B,C。

最后是测试代码

package final_activiti.progress;

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

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngineConfiguration;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.runtime.ProcessInstance;
import org.junit.Assert;
import org.junit.Test;
import org.mpc.final_activiti.MyProcessEngineConfiguration;

public class ConfigurationTest {

	@Test
	public void test() {
		MyProcessEngineConfiguration configuration = (MyProcessEngineConfiguration) ProcessEngineConfiguration
				.createProcessEngineConfigurationFromResource("my_config.xml",
						"myProcessEngineConfiguration");
		ProcessEngine p = configuration.buildProcessEngine();
		RepositoryService repositoryService = p.getRepositoryService();
		RuntimeService runtimeService = p.getRuntimeService();
		//这里我随便找了一个流程图部署
		repositoryService.createDeployment().addClasspathResource("final_activiti/progress/RecAndManulTask.bpmn").deploy();
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("123", configuration.getName());
		Assert.assertTrue("mpc_test".equals(configuration.getName()));
		ProcessInstance pi = runtimeService.startProcessInstanceByKey(
				"processRM", map);
		runtimeService.signal(pi.getId());
	}

}

测试结果,在junit中是绿色的,没问题。在控制台的输出如下:

一月 23, 2015 9:50:17 上午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [my_config.xml]
this is interceptor A org.activiti.engine.impl.SchemaOperationsProcessEngineBuild org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor C org.activiti.engine.impl.SchemaOperationsProcessEngineBuild org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor B org.activiti.engine.impl.SchemaOperationsProcessEngineBuild org.activiti.engine.impl.interceptor.CommandConfig
一月 23, 2015 9:50:19 上午 org.activiti.engine.impl.ProcessEngineImpl <init>
信息: ProcessEngine default created
一月 23, 2015 9:50:19 上午 org.activiti.engine.impl.jobexecutor.JobExecutor start
信息: Starting up the JobExecutor[org.activiti.engine.impl.jobexecutor.DefaultJobExecutor].
一月 23, 2015 9:50:19 上午 org.activiti.engine.impl.jobexecutor.AcquireJobsRunnableImpl run
信息: JobExecutor[org.activiti.engine.impl.jobexecutor.DefaultJobExecutor] starting to acquire jobs
this is interceptor A org.activiti.engine.impl.cmd.AcquireJobsCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor C org.activiti.engine.impl.cmd.AcquireJobsCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor B org.activiti.engine.impl.cmd.AcquireJobsCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor A org.activiti.engine.impl.cmd.DeployCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor C org.activiti.engine.impl.cmd.DeployCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor B org.activiti.engine.impl.cmd.DeployCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor A org.activiti.engine.impl.cmd.GetNextIdBlockCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor C org.activiti.engine.impl.cmd.GetNextIdBlockCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor B org.activiti.engine.impl.cmd.GetNextIdBlockCmd org.activiti.engine.impl.interceptor.CommandConfig
一月 23, 2015 9:50:19 上午 org.activiti.engine.impl.bpmn.deployer.BpmnDeployer deploy
信息: Processing resource final_activiti/progress/RecAndManulTask.bpmn
this is interceptor A org.activiti.engine.impl.cmd.StartProcessInstanceCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor C org.activiti.engine.impl.cmd.StartProcessInstanceCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor B org.activiti.engine.impl.cmd.StartProcessInstanceCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor A org.activiti.engine.impl.cmd.SignalCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor C org.activiti.engine.impl.cmd.SignalCmd org.activiti.engine.impl.interceptor.CommandConfig
this is interceptor B org.activiti.engine.impl.cmd.SignalCmd org.activiti.engine.impl.interceptor.CommandConfig

可以看到,定义的拦截器,按照他们加入责任链的顺序执行了,对每一个命令都有执行

posted @ 2015-01-23 09:50  qz程程  阅读(1711)  评论(0编辑  收藏  举报