推广 热搜:   公司  企业  中国  快速    行业  上海  未来  设备 

聊聊Mybatis的binding模块

   日期:2024-12-04     移动:http://fabua.ksxb.net/mobile/quote/3330.html

聊聊Mybatis的binding模块

public <T> void addMapper(Class<T> type) {    if (type.isInterface()) {      if (hasMapper(type)) {        throw new BindingException("Type " + type + " is already known to the MapperRegistry.");
      }      boolean loadCompleted = false;      try {
        knownMappers.put(type, new MapperProxyFactory<>(type));        // It's important that the type is added before the parser is run
        // otherwise the binding may automatically be attempted by the
        // mapper parser. If the type is already known, it won't try.
        MapperAnnotationBuilder parser = new MapperAnnotationBuilder(config, type);
        parser.parse();
        loadCompleted = true;
      } finally {        if (!loadCompleted) {
          knownMappers.remove(type);
        }
      }
    }
  }
@SuppressWarnings("unchecked")  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);    if (mapperProxyFactory == null) {      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    }    try {      return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {      throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
  }
先从knownMappers集合中找到对应的MapperProxyFactory实例

然后调用newInstance()方法
映射代理工厂类MapperProxyFactory

MapperProxyFactory的newInstance()方法:
public T newInstance(SqlSession sqlSession) {    final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);    return newInstance(mapperProxy);
  }  @SuppressWarnings("unchecked")  protected T newInstance(MapperProxy<T> mapperProxy) {    return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
  }
@Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {    try {      if (Object.class.equals(method.getDeclaringClass())) {        return method.invoke(this, args);
      } else {        return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
      }
    } catch (Throwable t) {      throw ExceptionUtil.unwrapThrowable(t);
    }
  }
private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {    try {      return MapUtil.computeIfAbsent(methodCache, method, m -> {        if (m.isDefault()) {          try {            if (privateLookupInMethod == null) {              return new DefaultMethodInvoker(getMethodHandleJava8(method));
            } else {              return new DefaultMethodInvoker(getMethodHandleJava9(method));
            }
          } catch (IllegalAccessException | InstantiationException | InvocationTargetException
              | NoSuchMethodException e) {            throw new RuntimeException(e);
          }
        } else {          return new PlainMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
        }
      });
    } catch (RuntimeException re) {
      Throwable cause = re.getCause();      throw cause == null ? re : cause;
    }
  }
从methodCache中获取对应的MapperMethodInvoker

如果缓存没有,如果是方法是default方法就创建DefaultMethodInvoker对象,否则创建PlainMethodInvoker对象
默认方法调用类DefaultMethodInvoker

对于DefaultMethodInvoker类通过MethodHandle完成调用
private static class DefaultMethodInvoker implements MapperMethodInvoker {    private final MethodHandle methodHandle;    public DefaultMethodInvoker(MethodHandle methodHandle) {      super();      this.methodHandle = methodHandle;
    }    @Override
    public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {      return methodHandle.bindTo(proxy).invokeWithArguments(args);
    }
  }
private static class PlainMethodInvoker implements MapperMethodInvoker {    private final MapperMethod mapperMethod;    public PlainMethodInvoker(MapperMethod mapperMethod) {      super();      this.mapperMethod = mapperMethod;
    }    @Override
    public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable {      return mapperMethod.execute(sqlSession, args);
    }
  }
本文地址:http://fabua.ksxb.net/quote/3330.html    海之东岸资讯 http://fabua.ksxb.net/ , 查看更多

特别提示:本信息由相关用户自行提供,真实性未证实,仅供参考。请谨慎采用,风险自负。


相关最新动态
推荐最新动态
点击排行
网站首页  |  关于我们  |  联系方式  |  使用协议  |  版权隐私  |  网站地图  |  排名推广  |  广告服务  |  积分换礼  |  网站留言  |  RSS订阅  |  违规举报  |  粤ICP备2023022329号