聊聊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);
}
}


