如下文章來源於公衆號「程序員求職之路」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原理,進一步提高操做數據庫能力。