MyBatis--自定义实现Mybatis责任链模式

Version:

  • jdk: 1.8
  • 项目地址MyBatis-source-learn

类图:

基本JDK 的reflect 包下通过动态代理的方式生成代理案例, 对method.invoke() 执行时进行增强,实现拦截器功能.

Main

具体实现:

Interceptor.java

package DesignPattern.chain;

// 拦截器
public interface Interceptor {
    /**
     *    拦截方法执行
     *
     */
        Object intercept(Invocation invocation) throws  Exception;
        // 将 target 与当前 interceptor 绑定
        default <T>T  plugin(Object target){
            return  TargetProxy.wrap(target,this);
        }
}

Interceptor接口的实现类

package DesignPattern.chain;

/**
 * @program: mybatis-source-learn
 * @description:
 * @author: WhyWhatHow
 * @create: 2021-03-14 13:43
 **/
public class TranslationInterceptor implements  Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws  Exception {
        System.out.println("------------- 事务 info start -----------");
        Object process = invocation.process();
        System.out.println("------------- 事务 info end --------------");
        return process;
    }
}
package DesignPattern.chain;

import java.lang.reflect.Method;

/**
 * @program: mybatis-source-learn
 * @description:
 * @author: WhyWhatHow
 * @create: 2021-03-14 13:43
 **/
public class LogInterceptor implements  Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws  Exception {
        System.out.println("------------- log info start -----------");
        Object process = invocation.process();
        System.out.println("------------- log info end --------------");
        return process;
    }
}

Invocation.java

package DesignPattern.chain;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * @program: mybatis-source-learn
 * @description: 方法的实现体
 * @author: WhyWhatHow
 * @create: 2021-03-14 13:27
 **/
public class Invocation  {

    private Method method;
    // 参数列表
    private Object[] args;

    public Invocation(Method method, Object[] args, Object target) {
        this.setMethod(method);
        this.setArgs(args);
        this.setTarget(target);
    }

    private Object target;
    // 执行目标方法
    Object process() throws InvocationTargetException, IllegalAccessException {
        return getMethod().invoke(getTarget(), getArgs());
    }

    public Method getMethod() {
        return method;
    }

    public void setMethod(Method method) {
        this.method = method;
    }

    public Object[] getArgs() {
        return args;
    }

    public void setArgs(Object[] args) {
        this.args = args;
    }

    public Object getTarget() {
        return target;
    }

    public void setTarget(Object target) {
        this.target = target;
    }
}

TargetProxy.java

package DesignPattern.chain;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * @program: mybatis-source-learn
 * @description: target对象的代理类
 * @author: WhyWhatHow
 * @create: 2021-03-14 13:30
 **/

public class TargetProxy  implements InvocationHandler {

    public TargetProxy(Interceptor interceptor, Object target) {
        this.interceptor = interceptor;
        this.target = target;
    }

    Interceptor interceptor;
    // 方法的实现体
//    Invocation invocation;
    // 代理对象
    Object target;
    //
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//        method.invoke(target,args);
//        interceptor.intercept(target);
        Invocation invocation =new Invocation(method,args,target);
        return  interceptor.intercept(invocation);

    }
    // 包装类
    public static <T>T wrap(Object target, Interceptor interceptor){
        TargetProxy targetProxy = new TargetProxy(interceptor, target);
        Object o = Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(),targetProxy );
        return (T) o;
    }
}

InterceptorChain.java

package DesignPattern.chain;

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

/**
 * @program: mybatis-source-learn
 * @description: // 拦截器链
 * @author: WhyWhatHow
 * @create: 2021-03-14 13:52
 **/
public class InterceptorChain {
    // 拦截器链
    List<Interceptor> list =new ArrayList<>();
    // 为target对象添加拦截器
    <T> T pluginAll(T target){
        for (Interceptor interceptor : list) {
            target =interceptor.plugin(target);
        }
        return target;
    }
    // 添加拦截器
    InterceptorChain add(Interceptor interceptor){
        list.add(interceptor);
        return this ;
    }

}

测试类:

package DesignPattern.chain;



//import DesignPattern.demo2.InvocationInterceptor;

import DesignPattern.Target;
import DesignPattern.TargetImpl;

/**
 * @program: mybatis-source-learn
 * @description:
 * @author: WhyWhatHow
 * @create: 2021-03-13 23:04
 **/
public class TestProxy {

    public static void main(String[] args) {

        //testWithoutChain();
        testWithChain();

    }

    private static void testWithoutChain() {
        System.out.println("------------no chain --------");
        LogInterceptor logInterceptor = new LogInterceptor();
        TranslationInterceptor translationInterceptor = new TranslationInterceptor();
//        InterceptorChain interceptorChain = new InterceptorChain();
        Target target =new TargetImpl();
        target = logInterceptor.plugin(translationInterceptor.plugin(target));
//        target = (Target) invocationInterceptorChain.pluginAll(target);
        target.execute(" HelloWord ");
    }
    private static void testWithChain() {
        System.out.println(" ==================chain========================");
        LogInterceptor logInterceptor = new LogInterceptor();
        TranslationInterceptor translationInterceptor = new TranslationInterceptor();
        InterceptorChain chain = new InterceptorChain();
        chain.add(translationInterceptor).add(logInterceptor);
        Target target =new TargetImpl();
        target = chain.pluginAll(target);
//        target = logInterceptor.plugin(translationInterceptor.plugin(target));
//        target = (Target) invocationInterceptorChain.pluginAll(target);
        target.execute(" HelloWord ");
    }
}

测试结果:

image-20210325005301666

参考:

  • https://blog.csdn.net/fuzhongmin05/article/details/107189863