加深理解Mybatis拦截器——基于动态代理和拦截器链来实现业务功能的扩展(比如日志和事务)

和上一篇文章的不同

  1. 加了两个拦截器对象;
  2. 多个拦截器组成拦截器链,在这里拦截器链内的主要作用是基于目标对象生成代理对象;
  3. 为调用目标方法的三个参数封装了一个Invacation对象,该对象的方法process方法代表用来业务方法
package test2;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.ArrayList;
import java.util.List;

/**
 * @author dubl @date:2019年12月12日
 */

//声明一个接口
interface Executor{
	void execute(String statement);
}
//接口的实现类(将来的目标对象)
class DefaultExecutor implements Executor{
	@Override
	public void execute(String statement) {
		System.out.println("execute"+statement);
	}
}
//对参数的封装以及目标对象方法的提取
class Invocation{
	private Object target;
	private Method method;
	private Object[] args;
	public Invocation(Object target, Method method, Object[] args) {
		this.target = target;
		this.method = method;
		this.args = args;
	}
	//执行业务方法
	public Object process() throws Exception{
		return method.invoke(target, args);
	}
}
//由于handler扩展的业务有限,会造成代码的冗余,所以构建了拦截器,来分担invoke方法里业务扩展的功能
interface Interceptor{
	Object interceptor(Invocation invocation) throws Exception;//把Invocation对象传过来
	Object plugin(Object target);//用来调用代理工厂,产生代理对象
}
class LogInterceptor implements Interceptor{
	@Override
	public Object interceptor(Invocation invocation) throws Exception {
		System.out.println("execute start"+System.nanoTime());
		Object result = invocation.process();
		System.out.println("execute end"+System.nanoTime());
		return result;	
	}
	@Override
	public Object plugin(Object target) {
		return TargetProxyFactory.newProxy(target, this);
	}
}
class TransactionInterceptor implements Interceptor{
	@Override
	public Object interceptor(Invocation invocation) throws Exception {
		System.out.println("transcation begin");
		Object result = invocation.process();
		System.out.println("transcation commit");
		return result;
	}
	@Override
	public Object plugin(Object target) {
		return TargetProxyFactory.newProxy(target, this);
	}
}
//责任链模式:把多个拦截器放在一个list集合里面,采用"击鼓传花"的方式产生代理对象
class InterceptorChain{
	private List<Interceptor> interceptors = new ArrayList<>();
	public void addInterceptor(Interceptor interceptor) {
		this.interceptors.add(interceptor);
	}
	//
	public Object pluginAll(Object target) {
		for(Interceptor interceptor:interceptors) {
			target = interceptor.plugin(target);
		}
		return target;
	}
}
//当代理对象执行目标方法时,需要具体的Handler去执行。
class TargetProxyHandler implements InvocationHandler{
	private Object target;
	private Interceptor interceptor;
	public TargetProxyHandler(Object target,Interceptor interceptor) {
		this.target = target;
		this.interceptor=interceptor;
	}
	
	@Override
	//在invoke方法实现业务的扩展
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		Invocation invocation = new Invocation(target, method, args);
		return interceptor.interceptor(invocation);//调用扩展业务的方法,并把里面需要的三个参数传递过去
	}
}
//生成代理对象的工厂
class TargetProxyFactory{
	public static Object newProxy(Object target,Interceptor interceptor) {
		return Proxy.newProxyInstance(
				target.getClass().getClassLoader(),//和目标对象使用同一个类加载器
				target.getClass().getInterfaces(),//和目标对象实现同一个接口
				new TargetProxyHandler(target,interceptor));//生成代理对象执行
	}
}
public class Test1 {
	public static void main(String[] args) {
		Executor target = new DefaultExecutor();//生成目标对象
		LogInterceptor logInterceptor = new LogInterceptor();
		TransactionInterceptor txInterceptor = new TransactionInterceptor();
		InterceptorChain interceptorChain = new InterceptorChain();;
		interceptorChain.addInterceptor(logInterceptor);
		interceptorChain.addInterceptor(txInterceptor);
		//Executor proxy = (Executor)TargetProxyFactory.newProxy(target,interceptor);//生成代理对象
		Executor proxy = (Executor)interceptorChain.pluginAll(target);//产生代理对象
		proxy.execute("statement");//代理对象调用
	}
}

代码执行结果:
加深理解Mybatis拦截器——基于动态代理和拦截器链来实现业务功能的扩展(比如日志和事务)_第1张图片

你可能感兴趣的:(Mybatis)