日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Mybatis源码分析--Mapper接口的代理生成原理

發布時間:2023/12/15 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Mybatis源码分析--Mapper接口的代理生成原理 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

下面是mapper接口代理的生成邏輯
進入源碼


進入getMapper看看


調用configuration的getMapper() 那么mapperRegistry是什么呢?我們看下

MapperRegistry含有兩個屬性。configuratio和Map。Map的key是class,value是MapperProxyFactory。那么,這個MapperProxyFactory又是什么呢? 看到該類的屬性,一個Class對象,即是我們定義的Mapper接口類。一個Map來表示方法緩存。看到2個newInstance方法,立馬想到應該是創建代理了。點開這兩個方法 根據給定的sqlsession和接口和方法緩存創建一個mapperProxy。該類實現了InvocationHandler。那么 我們進入到其invoke()方法 該方法首先判斷方法是否的Object類的方法,如果是,則不執行代理,直接進行。如果不是,執行cachedMapperMethod 方法 并調用返回對象 MapperMethod 的execute 方法。我們看看cachedMapperMethod方法,應該和緩存有關.

private MapperMethod cachedMapperMethod(Method method) {return methodCache.computeIfAbsent(method, k -> new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));} 復制代碼

看下 MapperMethod的構造方法,構造了SqlCommand和MethodSignature兩個對象。它們都是MapperMethod的靜態內部類。
SqlCommand類有2個屬性,它們是怎么得到的呢?從resolveMappedStatement()方法的返回值得到的。我們進入該方法看下

public static class SqlCommand {private final String name;//表示sql語句的名稱private final SqlCommandType type;//表示sql語句的類型public SqlCommand(Configuration configuration, Class<?> mapperInterface, Method method) {final String methodName = method.getName();final Class<?> declaringClass = method.getDeclaringClass();MappedStatement ms = resolveMappedStatement(mapperInterface, methodName, declaringClass,configuration);if (ms == null) {if(method.getAnnotation(Flush.class) != null){name = null;type = SqlCommandType.FLUSH;} else {throw new BindingException("Invalid bound statement (not found): "+ mapperInterface.getName() + "." + methodName);}} else {name = ms.getId();type = ms.getSqlCommandType();if (type == SqlCommandType.UNKNOWN) {throw new BindingException("Unknown execution method for: " + name);}}}private MappedStatement resolveMappedStatement(Class<?> mapperInterface, String methodName,Class<?> declaringClass, Configuration configuration) {//獲取idString statementId = mapperInterface.getName() + "." + methodName;if (configuration.hasStatement(statementId)) {return configuration.getMappedStatement(statementId);} else if (mapperInterface.equals(declaringClass)) {return null;}for (Class<?> superInterface : mapperInterface.getInterfaces()) {if (declaringClass.isAssignableFrom(superInterface)) {MappedStatement ms = resolveMappedStatement(superInterface, methodName,declaringClass, configuration);if (ms != null) {return ms;}}}return null;} 復制代碼

SqlCommandType是枚舉。
拿到mapperMethod,進入excute();
此時返回代理對象

public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {this.command = new SqlCommand(config, mapperInterface, method);this.method = new MethodSignature(config, mapperInterface, method);} 復制代碼

my.oschina.net/heweipo/blo…

通過上面的代碼,我們拿到了代理。那么,如何用這個代理呢?利用這個代理會代理到什么方法上呢?
那么既然有了 MapperProxy 對象,只要在這個對象的invoke方法里調用執行 SQL 語句就達到目的了,因此也就不需要接口實現類了

轉載于:https://juejin.im/post/5b514c56f265da0f4d0d748e

總結

以上是生活随笔為你收集整理的Mybatis源码分析--Mapper接口的代理生成原理的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。