一、mybatis使用动态代理要实现的功能。

mybatis 的底层实际上运行的还是ibatis,即需要把接口和xml映射翻译成 ibatis 需要的这种格式。

在这里插入图片描述

二、mapper接口的动态代理

  1. 当使用 sqlSession.getMapper 获取一个Mapper 的时候一般是使用 sqlSessionDefaultSqlSession 这个实现类去调用的。
  2. 先去调用 configuration.getMapper。然后会从mapperRegistryknownMappers中拿到接口对应的MapperProxyFactory
  3. MapperProxyFactory会创建出来mapper接口的代理实现类(严格的讲,这生成的只是一个接口的代理,算不上一个真正的实现),并把他交给 MapperProxy 管理。
  4. 然后把代理的实现类返回。

三、mapper接口调用方法

  1. 上文讲到通过sqlsession拿到的是一个经过动态代理的mapper。所以在mapper调用方法的时候,会进入代理对象 MapperProxy的invoke方法。
  2. MapperProxy.invoke,方法中会创建一个MapperMethod对象。这个对象封装了Mapper接口中对应方 法的信息,以及对应的sql语句的信息。
  3. 接下来就会调用MapperMethod 的 execute方法。在这里就会真正执行ibatis的部分。

四、问题:mybatis 的mapper接口没有实现类,那么他是如何工作的

  1. 有些文章中说,mybatis是通过动态代理的方式,生成了mapper接口的实现类,其实这种表达是很不准确的。动态代理并没有替mapper接口生成实现类,而是利用动态代理的方式使接口每次执行方法的时候,都会经过代理类的invoke 方法来做一些操作。
  2. mybatis 的运行,最终都会进入到ibatis 的运行方式来,看ibatis 的运行方式,是并没有mapper接口参与的。所以mybatis 的mapper接口类更像是一个工具人。
  3. mapper接口工具人论述。
    1. 接口被动态的代理了,所以他执行的所有方法都会进入到代理类的invoke方法中。所以使用接口调用方法的目的,只是为了执行代理类的invoke方法而已,工具人mapper 接口只是为代理类跑腿而已
    2. mapper接口的每个方法会定义 入参类型、出参类型,在调用接口方法时候还会往里面传入具体参数。所以mapper接口只是为了让ibatis调用selectOne、selectList等方法时运送 这些关键信息的而已。
Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐