Mybatis源码--MapperProxyFactory&MapperProxy源码分析

1 概述

针对这里的源码分析,我们首先要搞清楚java动态代理,因为就因为这里使用了java动态代理,才能够让我们在并没有mapper接口实现类对应的bean的情况下也能够进行依赖注入。

2 MapperProxyFactory

这个类的主要作用是用于生成mapper接口的Proxy代理。
我们直接来看一下源码。

import org.apache.ibatis.session.SqlSession;

/**
 * @author Lasse Voss
 */
public class MapperProxyFactory<T> {

  private final Class<T> mapperInterface;  //mapper接口
  private final Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>();  //mapper接口中对应的method与xml节点封装MapperMethod的map

  public MapperProxyFactory(Class<T> mapperInterface) {
    this.mapperInterface = mapperInterface;
  }

  public Class<T> getMapperInterface() {
    return mapperInterface;
  }

  public Map<Method, MapperMethod> getMethodCache() {
    return methodCache;
  }

  @SuppressWarnings("unchecked")
  protected T newInstance(MapperProxy<T> mapperProxy) {
	
    //生成接口的代理类	
    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }

  public T newInstance(SqlSession sqlSession) {
	  
    //初始化MapperProxy,这个MapperProxy其实是InvokeHandler类的实现类  
    final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
    return newInstance(mapperProxy);
  }

}

从上面的源码我们得知,MapperProxyFactory的作用其实就是生成Mapper接口的动态代理对象。其实在我们添加依赖注入的时候注入到Spring容器中的也就是这个动态代理对象。

3 MapperProxy

由上面的分析可以猜想MapperProxy实现了主要的动态代理逻辑,我们直接看一看源码。

/**
 * @author Clinton Begin
 * @author Eduardo Macarron
 */
public class MapperProxy<T> implements InvocationHandler, Serializable {

    private static final long serialVersionUID = -6424540398559729838L;
    private final SqlSession sqlSession;
    private final Class<T> mapperInterface;
    private final Map<Method, MapperMethod> methodCache;

    public MapperProxy(SqlSession sqlSession, Class<T> mapperInterface, Map<Method, MapperMethod> methodCache) {
        this.sqlSession = sqlSession;
        this.mapperInterface = mapperInterface;
        this.methodCache = methodCache;
    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        //判断method是否是属于Object类,如果是则直接执行  
        if (Object.class.equals(method.getDeclaringClass())) {
            try {
                return method.invoke(this, args);
            } catch (Throwable t) {
                throw ExceptionUtil.unwrapThrowable(t);
            }
        }

        //获取method对应的MapperMethod封装,直接执行execute。
        final MapperMethod mapperMethod = cachedMapperMethod(method);
        return mapperMethod.execute(sqlSession, args);
    }

    private MapperMethod cachedMapperMethod(Method method) {
        MapperMethod mapperMethod = methodCache.get(method);
        if (mapperMethod == null) {
            mapperMethod = new MapperMethod(mapperInterface, method, sqlSession.getConfiguration());
            methodCache.put(method, mapperMethod);
        }
        return mapperMethod;
    }

}

从上面我们知晓MapperProxy的invoke方法实际上是把Mapper接口方法包装为了MapperMethod,并执行的MapperMethod的execute方法。

上面我们完成了MapperProxyFactory&MapperProxy源码分析,我们将继续进行Mybatis的其余内容进行分析,欢迎交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值