上篇-原生mybatis流程
因Mapper是interface,不能实例化对象,以是必须使用动态署理(使用JDK动态署理)创建署理对象MapperProxy,又因Mapper是接口,没有具体的方法体,以是MapperProxy的invoke方法中自行编写方法逻辑,下面先容CURD的实行过程。
public class MapperProxy<T> implements InvocationHandler, Serializable {略@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; } }}###调用MapperBean中的非default方法 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); } }可见mapperMethod来实行execute,携带sqlSession和参数(默认的statement是prepareStatement)
mapperMethod类中有2个属性,分别是SqlCommand、MethodSignature,均是MapperMethod的内部类。
public class MapperMethod { private final SqlCommand command; private final MethodSignature method; public static class SqlCommand { 类全路径名+方法名:com.orion.mapper.TAccountMapper.selectByPrimaryKey private final String name; 罗列,CURD那几种,如SELECT private final SqlCommandType type; } public static class MethodSignature { private final boolean returnsMany; private final boolean returnsMap; private final boolean returnsVoid; private final boolean returnsCursor; private final boolean returnsOptional; 返回范例 private final Class<?> returnType; private final String mapKey; private final Integer resultHandlerIndex; private final Integer rowBoundsIndex; 参数 private final ParamNameResolver paramNameResolver; } }SELECT