手写(模拟)实现Mybaits中的拦截器 (动态代理+责任链模式)

本文为方便看,多个class 写再一起!

Mybatis 中的拦截器主要是通过动态代理+责任链模式实现的、该代码是本人在学习Mybatis过程中手写写模拟拦截器实现方式!

代码可执行!

1、拦截器接口以及实现类

package com.example.demo.Intercepter;

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

public interface Intercepter {

    Object intecepter(Invocation invocation) throws Exception;

    default Object plugin(Object target){
        return TargetProxyFactory.newProxy(target,this);
    }
}



class IntercepterChain {

    private List intercepters = new ArrayList<>();

    public void addIntercepter(Intercepter intercepter) {
        this.intercepters.add(intercepter);
    }


    public Object pluginAll(Object target) {
        for (Intercepter intercepter : intercepters) {
            target = intercepter.plugin(target);
        }
        return target;
    }
}


class MyIntecepter implements Intercepter {

    @Override
    public Object intecepter(Invocation invocation) throws Exception {

        System.out.println("执行了MyIntecepter! 拦截器");
        Object result =invocation.process();

        return result;
    }


//    public Object plugin(Object target) {
//        return TargetProxyFactory.newProxy(target,this);
//    }

}


class LogIntercepter implements Intercepter{

    @Override
    public Object intecepter(Invocation invocation) throws Exception {

        System.out.println("LogIntercepter--- 执行日志拦截器!");
       
        return  invocation.process();
    }
}

 

 2、拦截对象

package com.example.demo.Intercepter;

public interface Executor {
    void excute(String  statement);
}

class DefaultExcutor implements Executor{

    @Override
    public void excute(String statement) {

        System.out.println("DefaultExcutor====\t"+statement);
    }
}

 

3、ProxyHandler (代理处理器)及测试类

package com.example.demo.Intercepter;

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

/**
 * @author fuwenshen
 * @description 拦截器 (代码模式+责任链模式)
 * @date 2020/3/25
 */


/**
 * Invocation  用于保存代理对应反射嗲用需要的数据 ,方便传递
 */
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);
    }
}


/***
 * 代理处理器
 */
class TargetProxyHandler implements InvocationHandler{

    Intercepter intercepter;
    Object target;
    public TargetProxyHandler(Object target,Intercepter intercepter) {
        this.target = target;
        this.intercepter = intercepter;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
         Invocation invocation = new Invocation(target,method,args);
        return intercepter.intecepter(invocation);
    }

}



/**
 * 创建一个动态代理类工厂类
 */

class TargetProxyFactory {

    public static Object newProxy(Object target, Intercepter intercepter) {
        return Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                new TargetProxyHandler(target, intercepter));
    }

}




public class TestIntercepter {


    public static void main(String[] args) {

        // 拦截的目标对象
        Executor target= new DefaultExcutor();


        // 定义的拦截器
        MyIntecepter myIntecepter = new MyIntecepter();
        LogIntercepter logIntercepter = new LogIntercepter();

        // 加入到拦截器链表中
        IntercepterChain  intercepterChain = new IntercepterChain();
        intercepterChain.addIntercepter(myIntecepter);
        intercepterChain.addIntercepter(logIntercepter);

        Executor proxy = (Executor) intercepterChain.pluginAll(target);

        proxy.excute("select * from test");
        

    }
}

 


Test输出结果:

LogIntercepter--- 执行日志拦截器!
执行了MyIntecepter! 拦截器
DefaultExcutor====    select * from test

你可能感兴趣的:(JAVA,Mybatis)