mybatis执行流程与设计思路

53 阅读1分钟

代理回顾

Spring代理与责任链中讲到代理:JDK代理、Cglib代理,核心是使用Proxy.newProxyInstance方法生成一个接口的代理实例

原生jdk代理代码示例:

public interface BrandMapper {
    List getAll();
}
public class DefaultBrandMapper implements BrandMapper {
    @Override
    public List getAll() {
        System.out.println("DefaultBrandMapper....");
        return null;
    }
}
//代理都需要实现InvocationHandler,被代理接口所有方法的执行都会进入代理的invoke方法
public class MapperProxy<T> implements InvocationHandler {
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //这里为什么会有一个if判断
        if (Object.class.equals(method.getDeclaringClass())) {
            return method.invoke(this, args);
        }
        System.out.println("进入代理1:" + method);
        //这里的proxy就是main函数中brandMaper指向的一个Proxy实例,下面的打印会调用brandMapper.toString(),由于被代理又进入invoke,若没有上述if,就会递归
        System.out.println("进入代理2:" + proxy);
        //执行DefaultBrandMapper实例的method方法
        method.invoke(new DefaultBrandMapper(),args);
        return null;
    }
    @Override
    public String toString() {
        System.out.println("MapperProxy toString");
        return "111";
    }
}
public class MapperProxyFactory<T> {
    private final Class<T> mapperInterface;
    public MapperProxyFactory(Class<T> mapperInterface) {
        this.mapperInterface = mapperInterface;
    }
    protected T newInstance(MapperProxy<T> mapperProxy) {
        return (T) Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
    }
}
public class ProxyTest {
    public static void main(String[] args) {
        MapperProxyFactory mapperProxyFactory = new MapperProxyFactory(BrandMapper.class);
        BrandMapper brandMapper = (BrandMapper) mapperProxyFactory.newInstance(new MapperProxy<BrandMapper>());
        brandMapper.getAll();
    }
}

再看注释

/**
 * Returns an instance of a proxy class for the specified interfaces
 * that dispatches method invocations to the specified invocation
 * handler.
 * 为指定的接口返回Proxy类型的实例,该Proxy实例将方法调用发送到指定的
 * InvocationHandler的invoke方法
 */
Object Proxy::newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
/**
 * proxy the proxy instance that the method was invoked on
 * proxy类型的实例,方法被调用在该实例上。就是上面newProxyInstance的返回值
 */
Object InvocationHandler::invoke(Object proxy, Method method, Object[] args)

源码解读

执行流程

image.png

重要接口与类

mapper接口实例化与容器托管

常用设计模式