小程序原生组件—提升你的小程序体验
810
2022-10-20
聊聊Mybatis的binding模块
聊聊Mybatis的binding模块
为什么我们在使用Mybatis的时候只需要写接口和xml文件就能执行sql呢?这就是Mybatis的binding模块需要做的事情了,今天我们分析一下Mybatis的binding模块,binding包下的类主要有四个MapperRegistry、MapperProxyFactory、MapperProxy和MapperMethod 映射注册类MapperRegistry
MapperRegistry是个注册类,它的knownMappers集合保存着Mapper接口和MapperProxyFactory实例的映射关系
它的addMapper()方法就是添加映射关系的方法:
public
当传入的type是个接口并knownMappers中没有,就把type和对应的MapperProxyFactory实例放入knownMappers中
然后在执行sql的时候,Mybatis会调用MapperRegistry.getMapper()方法
@SuppressWarnings("unchecked") public
先从knownMappers集合中找到对应的MapperProxyFactory实例然后调用newInstance()方法映射代理工厂类MapperProxyFactoryMapperProxyFactory的newInstance()方法:
public T newInstance(SqlSession sqlSession){ final MapperProxy
生成mapperInterface接口 的代理对象的实例,代理类是MapperProxy,它实现了InvocationHandler,利用jdk动态代理生成代理对象
看一下它重写的invoke()方法: 映射代理类MapperProxy
MapperProxy的invoke()方法:
@Override public Object invoke(Object proxy, Method method, Object[] args) throws{ 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
不是Object的类会被拦截,拦截调用cachedInvoker()方法,其他执行invoke()方法,
private MapperMethodInvoker cachedInvoker(Method method) throws{ 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
从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{ return
对于普通方法对应的类PlainMethodInvoker通过MapperMethod来完成调用,
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{ return
总结
这篇文章主要介绍了聊聊Mybatis的binding模块,它的MapperRegistry保存着Mapper接口和MapperProxyFactory实例的映射关系,而MapperProxyFactory是一个的工厂,生成的是Mapper接口的代理类,MapperProxy实现InvocationHandler,重写invoke()方法进行拦截处理,根据方法判断是不是default类型创建不同的MethodInvoker类,然后调用MapperMethod执行sql,下篇文章我们将介绍MapperMethod类
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~