如下文章来源于公众号“程序员求职之路”java
在java程序员的世界里,最熟悉的开源软件除了 Spring,Tomcat,还有谁呢?固然是 Mybatis 了。MyBatis 是一个被普遍应用的持久化框架。代理模式能够认为是Mybatis的核心使用的模式。本文经过代理模式,带你掌握MyBatis原理。程序员
01spring
什么是代理模式sql
代理模式含义是为其余的对象提供一种代理以难以控制对这个对象的访问,简而言之即若是有一些咱们不能作不想作的事情,能够委托别人去作。优势是能够不用修改源代码。数据库
代理模式的角色分类有抽象主题(接口)、具体主题(真实类)和proxy(代理类)。mybatis
代理模式的角色分类app
02框架
静态代理与动态代理工具
代理模式又分为静态理和动态代理,动态代理又有两种,一种是JDK动态代理,一种是Cglib。spa
静态代理与动态代理
静态代理是必需要有java源文件,经过java编译器转换为.calss文件,经过转换转为byte类加载器再进行加载。
动态代理直接在运行时就生成byte文件直接经过类加载器进行加载。
JDK动态代理要求必须是实现接口那种方式,不然不能进行动态代理。
Cglib支持不是接口的类能进行动态代理,可是Cglib不能代理被final修饰的方法。Springboot 2.x版本spring已经添加了cglib。
若是是实现接口类型的就用jdk动态代理,若是不是接口类型就用Cglib。
03
为何须要动态原理?
缘由是代码运行的时自动生成代理类,帮咱们作额外咱们想作的事情。
动态代理实现方法有JDK Proxy和用JDK里的工具自动生成动态代理类两种。
动态代理流程
Client假如就是main方法,doSomething就是调用任何方法它都会生成$Proxy类,$Proxy类调用invoke方法,走到咱们本身定义的任何代理类方法调用invoke开始作加强代码逻辑的操做,而后再调用被代理对象的方法。
04
JDK动态原理分析
1首先对咱们传进来的接口InvocationHandler所有克隆了一遍(必须实现Invocationhandler的接口)
2生成一个代理类class对象(get proxy0生成对象)
3根据代理类对象cl,获取构造器
4根据构造器和InvocationHandler实现类,建立代理类实例(使用newInstance)
05
MyBatis动态原理的使用
mapper语句
这是一段Mybatis的一个查询数据库数据的代码,经过mapper找到配置文件的sql语句,执行sql语句获取数据,可是mapper.selectBlogById()它是没有实现类的,那是怎么实现操做方法的呢?
打印一下类信息,发现此时的mapper实际上是动态代理出来的类了
发现输出的是jdk的动态代理
那MyBatis中的hadler是什么呢,是MapperProxy里的invoke方法,也就是说可以不实现接口就直接调用来运行sql语句是经过了jdk动态代理实现的,sql操做都在mapperMethod里的execute里实现的。
Mybatis插件
Mybatis拦截器、分页插件等一些其余插件都是使用了动态代理,那么mybats里有专门的Plugin代理类, 下图二Plugin类的invoke
Mybatis的链接池
若是不指定spring管理数据库链接,mybatis也是有链接池的,而池的操做mybatis也是采用动态代理。由于connection的链接本身是不可能把本身还给池子里的,而connection自己没有池,那么只能经过代理方式加强链接池的功能,代理类帮它把connection放回池操做等等。
invoke的实现就是假如你要释放链接,那么判断方法是否是CLOSE,而后把链接放入dataSource容器,最后return也都是调回被代理方法的自己操做的方法
Mybatis的日志
Mybatis会打印执行sql日记,确定不能在业务里写,因此也须要代理模式
ConnectionLogger打印日志。
代理模式在MyBatis中常常使用,但愿这篇文章能让你掌握MyBatis原理,进一步提高操做数据库能力。