mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper

xjz1842發表於2018-05-04

這一篇是緊接著上一篇文章 基於springboot的配置載入和sqlsessionFactory構造寫的,這篇文章將要介紹Mapper介面的掃描和載入。

mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
從圖上可以看出這個@MapperScan註解是一個複合註解,它同時擁有了@Import(MapperSannerRegistrar), 這個是掃描非常重要的類。

mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper

可以看出該類實現了ImportBeanDefinitionRegistrar和ResourceLoaderAware, 實現ResourceLoaderAware介面,spring容器會自動注入一個resourseLoader的實現類,實現了ImportBeanDefinitionRegistrar則會自動呼叫registerBeanDefinitions方法,來向Spring容器注入bean, 具體可參考這篇文章 https://www.cnblogs.com/zzq-include/p/8004506.html 除錯發現注入的ResourceLoader實際的例項是AnnotationConfigEmbeddedWebApplication這個類,
mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
這個方法主要是用ClassPathMapperScanner這個類去掃描路徑然後注入到Spring的容器中,前面主要在設定scan的屬性,重點看一最後兩行scan.registerFilter和scan.doScan.
mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
registerFileters這個方法,可以看到這個方法中,如果我們不配置MapperScan中的annotationClass屬性時,那麼預設掃描的的配置包路徑處理package-info類的所有的介面,接下來看下掃描類doScan做了哪些事。

mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
執行掃描類,主要處理是在postBeanDefinitions方法中處理的,
mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
從圖中最後三行分別是在初始化注入Mapper介面類全名,設定注入spring容器的中BeanDefinition的實際BeanClass是MapperFacotyBean這個類,設定MapperFactoryBean例項物件addToConfig的值為true,

mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
方法的後半部分都是設定beandefinition的屬性,還有最重要要的是definition設定AuotWiredMode的值為AUTOWIRE_BY_TYPE,是該bean是的含有set的方法的屬性會按照的型別自動裝配。下面來一下MapperFactoryBean這個類,

mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
它是繼承自SqlSessionSupport這個類並實現FactoryBean這個介面,從前面介紹過這裡的MapperInterface就是掃描的Mapper介面通過建構函式注入進來的
mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
從這裡看出MapperFactoryBean這個類獲取的bean是通過SqlSession構造的getMapper方法得到的.

mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
從上圖看出MapperFacotoryBean的結構,在初始化這個bean會呼叫afoterPropertiesSet這個方法(這個是Spring的bean的生命週期的鉤子方法),這個方法MapperFacotoryBean也實現了。
mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
可以看出這個方法裡,才是向Configuration中注入mapper的地方。繼續看Configuration的addMapper方法。
mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper

mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
這個方法是MybatisMapperRegistry這個類中註冊mapper這個介面,那麼mybatisMapperRegistry是怎麼註冊這個介面的,接著往下看,

mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
上面這段截圖是MybatisMapperRegistry的addMapper這個方法,實際這個類中定義了Map,key為Mpper介面的class,value是MapperProxyFacotry這個類註冊介面的,MapperProxyFacotry這個類是Mapper代理的構造的工廠類。
mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
這個就是包含的屬性是介面的class,以及這個類的快取方法。最後一個方法是 建立動態代理的方法,

mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
可以看到MapperProxy是實現InvocationHandler這個介面,顯然這裡用的是JDK的實現的動態代理實現的,前面註冊的時候,是註冊的是MapperProxyFactory這個例項,俺麼建立代理是在什麼時候進行的呢?既然不是在註冊的時候注入的,那麼可能是呼叫時建立的,下面看一個getMapper這個方法
mybatis-plus原始碼解析(二)----基於@MapperScan註解掃描載入Mapper
可以看到在這裡 獲取的MapperProxyFactory呼叫了呼叫了newInstance來建立這個代理,到這裡Mapper的註冊過程就基本完成了。

總結: 今天主要介紹了Mapper介面的掃描和載入介面並註冊Mapper介面的代理工廠,下一篇將會介紹Mapper介面是如何通過使用動態代理來呼叫執行的過程. 。

相關文章