接口式编程原理
讲解接口式原理之前需了解如下几个问题

问题1:没有实现类的接口为甚么可以实现方法的功能(答案:是通过动态代理。简单的动态代理过程,是要有一个实现InvocationHandler接口的类,这里给这个类起名为MapperProxy,因为Mybatis源码中就是起的这个名称,这个类必须实现invoke()方法。然后用这个类通过Proxy.newProxyInstance(类加载器,接口,MapperProxy对象)创建一个代理实例,在案例中是通过sqlSession.getMapper()获取到代理实例的,表面上看是使用接口承接的,但该对象不是实现类的对象,而是一个代理实例,然后是通过这个代理实例调用接口里的方法,由动态代理知识,它并不会执行这个方法,而是会触发MapperProxy的invoke()方法,这样没有实现类的接口方法就可以执行了)。

问题2:虽然调用接口方法时,走的是invoke()方法,怎么知道调用的sql语句是什么样子的呢?(因为调用的sql语句在配置文件中,在获取SqlSession对象之前,由于调用加载Mybatis核心配置文件的方法,Mybatis配置文件中引入了sql配置文件的路径,这样加载Mybatis总配置文件的同时,也把其他配置文件加载了,这些信息Mybatis会存储到对象(Configuration)中,当代理实例调用接口方法时,如果该接口方法与配置信息能对应上(配置文件的namespace等于包名+接口名,方法名等于id名,接口参数等于parameterType,返回值类型等于resultType),就可以成功调用,根据上节课知识,这里是存在某种联系的——>接口的全名称就是配置文件的namespace,调用的方法名就是定义sql标签的id,接口的全名称和调用的方法名在invoke()方法中是可以获取到的,有了这些信息就可以获取到配置文件信息,然后再invoke方法里就可以代替原来写的方法)

问题3:根据动态代理的知识,Proxy.newProxyInstance()返回的是Object类型的对象,但却赋值给接口类型的对象?
(答案:这里是泛型的作用,当使用getMapper()传入的是什么样的类类型,就可以使用什么样的类型去接值,这就是Mybatis利用泛型进行强转了)。

接口式编程原理
讲解接口式原理之前需了解如下几个问题

问题1:没有实现类的接口为甚么可以实现方法的功能(答案:是通过动态代理。简单的动态代理过程,是要有一个实现InvocationHandler接口的类,这里给这个类起名为MapperProxy,因为Mybatis源码中就是起的这个名称,这个类必须实现invoke()方法。然后用这个类通过Proxy.newProxyInstance(类加载器,接口,MapperProxy对象)创建一个代理实例,在案例中是通过sqlSession.getMapper()获取到代理实例的,表面上看是使用接口承接的,但该对象不是实现类的对象,而是一个代理实例,然后是通过这个代理实例调用接口里的方法,由动态代理知识,它并不会执行这个方法,而是会触发MapperProxy的invoke()方法,这样没有实现类的接口方法就可以执行了)。

问题2:虽然调用接口方法时,走的是invoke()方法,怎么知道调用的sql语句是什么样子的呢?(因为调用的sql语句在配置文件中,在获取SqlSession对象之前,由于调用加载Mybatis核心配置文件的方法,Mybatis配置文件中引入了sql配置文件的路径,这样加载Mybatis总配置文件的同时,也把其他配置文件加载了,这些信息Mybatis会存储到对象(Configuration)中,当代理实例调用接口方法时,如果该接口方法与配置信息能对应上(配置文件的namespace等于包名+接口名,方法名等于id名,接口参数等于parameterType,返回值类型等于resultType),就可以成功调用,根据上节课知识,这里是存在某种联系的——>接口的全名称就是配置文件的namespace,调用的方法名就是定义sql标签的id,接口的全名称和调用的方法名在invoke()方法中是可以获取到的,有了这些信息就可以获取到配置文件信息,然后再invoke方法里就可以代替原来写的方法)

问题3:根据动态代理的知识,Proxy.newProxyInstance()返回的是Object类型的对象,但却赋值给接口类型的对象?
(答案:这里是泛型的作用,当使用getMapper()传入的是什么样的类类型,就可以使用什么样的类型去接值,这就是Mybatis利用泛型进行强转了)。

1、没有实现类的接口为什么能执行定义的方法?
通过动态代理
解决接口式编程的几个问题:
1、没有实现类的接口为什么能执行定义的方法?
通过动态代理的方式。

2、mybatis如何知道调用的哪条sql语句?(MapperProxy.invoke()==sqlqSession.selectList())


3、用接口接返回的对象不报错(IMessage iMessage = Proxy.neProxyInstance())?
泛型在起作用,mybatis在返回对象时已经做了强制类型转换,无需自己手动转换
模式