成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring整合MyBatis之底層原理

原創(chuàng) 精選
數(shù)據(jù)庫(kù) 其他數(shù)據(jù)庫(kù)
使用起來(lái)是很簡(jiǎn)單的,但是有沒(méi)有老鐵想過(guò),為什么做了這么一個(gè)簡(jiǎn)單的配置,這個(gè)Mapper就能操作數(shù)據(jù)庫(kù)了?

作者 | 波哥

審校 | 孫淑娟

如果老鐵們對(duì)Spring框架足夠熟悉,整合MyBatis其實(shí)很容易理解,當(dāng)然這里假定老鐵們也已經(jīng)熟悉了MyBatis框架。

在我們正常的應(yīng)用開(kāi)發(fā)過(guò)程中,使用MyBatis一般分為如下幾個(gè)步驟:

1.在配置類(lèi)上增加MapperScan注解,例如:@MapperScan(basePackages = {"com.test.dao"},annotationClass = Mapper.class);

2.在basePackages指定的目錄下創(chuàng)建待MyBatis讀取的接口文件,例如:

@Mapper
public interface TestMapper {
......
}

3.在Service或者其他地方使用該Mapper來(lái)操作數(shù)據(jù)庫(kù)。

使用起來(lái)是很簡(jiǎn)單的,但是有沒(méi)有老鐵想過(guò),為什么做了這么一個(gè)簡(jiǎn)單的配置,這個(gè)Mapper就能操作數(shù)據(jù)庫(kù)了?按理說(shuō)這個(gè)Mapper是個(gè)接口,應(yīng)該是不能被創(chuàng)建才對(duì)啊!如果你有這個(gè)疑問(wèn),證明你是個(gè)愛(ài)思考的好童鞋。

咱們直接進(jìn)入主題。Spring要與MyBatis整合,簡(jiǎn)單來(lái)說(shuō)只要解決如下兩個(gè)問(wèn)題:

一、Spring如何知道哪些類(lèi)應(yīng)該被管理?

要讓Spring去管理Bean的生命周期,首先需要對(duì)應(yīng)的類(lèi)被Spring掃描到,并且生成DeanDefinition,然后基于BeanDefinition生成Bean。下面對(duì)Spring生成BeanDefinition的方式做個(gè)小總結(jié):

  • 包含Component、Configuration、ComponentScan、Import、ImportResource注解的類(lèi);
  • Import注解中指定的類(lèi)、被Bean注解標(biāo)注的方法所在的類(lèi);
  • 實(shí)現(xiàn)了ImportBeanDefinitionRegistrar接口,并且在registerBeanDefinitions方法中調(diào)用registry直接注冊(cè)的類(lèi);
  • 實(shí)現(xiàn)了ImportSelector接口,并且在selectImports方法中返回的字符串對(duì)應(yīng)的類(lèi);
  • 直接調(diào)用register方法;
  • 另外Spring還提供了一個(gè)擴(kuò)展,可以讓開(kāi)發(fā)者自己指定需要被管理的類(lèi)對(duì)應(yīng)的類(lèi)型:通過(guò)往includeFilters中添加注解類(lèi)類(lèi)型。

我們分析源碼,第一步得找到它的入口,Spring整合MyBatis的入口,毫無(wú)疑問(wèn)是MapperScan這個(gè)注解,在MapperScan注解上包含Import(MapperScannerRegistrar.class)注解,Spring整合MyBatis正是用了Import和ImportBeanDefinitionRegistrar的方式。我們先通過(guò)一張流程圖來(lái)了解下整體流程,然后再慢慢品。

圖片

我們來(lái)看MapperScannerRegistrar這個(gè)類(lèi)的繼承關(guān)系圖:

圖片

MapperScannerRegistrar是ImportBeanDefinitionRegistrar的實(shí)現(xiàn)類(lèi),Spring會(huì)去調(diào)用這個(gè)類(lèi)的registerBeanDefinitions方法添加beanDefinition,這個(gè)方法中具體做了些什么呢:

獲取MapperScan注解的配置信息,比如basePackages、annotationClass,basePackages表示需要掃描的路徑,annotationClass則是指定了增加了這種注解類(lèi)的類(lèi)需要被Spring進(jìn)行管理,比如增加了Mapper注解的類(lèi)需要被Spring管理。

生成MapperScannerConfigurer這個(gè)類(lèi)型的beanDefinition,并且把MapperScan注解的配置信息添加到該beanDefinition的屬性集合中。

后續(xù)Spring就會(huì)基于這個(gè)MapperScannerConfigurer做一系列文章,看下它的繼承關(guān)系:

圖片

它是BeanDefinitionRegistryPostProcessor的實(shí)現(xiàn)類(lèi),是一個(gè)BeanFactory后置處理器,Spring會(huì)調(diào)用該類(lèi)的postProcessBeanDefinitionRegistry方法來(lái)添加beanDefinition的操作,MapperScannerConfigurer這個(gè)類(lèi)中具體實(shí)現(xiàn)如下:

圖片

它定義了ClassPathMapperScanner這個(gè)掃描器,然后使用這個(gè)掃描器來(lái)掃描類(lèi),掃描哪些類(lèi)呢?掃描有Mapper注解的類(lèi),看它的關(guān)系知道,它是ClassPathBeanDefinitionScanner的子類(lèi),而spring則是使用ClassPathBeanDefinitionScanner來(lái)進(jìn)行掃描的。

圖片

為什么ClassPathMapperScanner能夠掃描到帶有Mapper注解的類(lèi)呢?看上面代碼,就是通過(guò)調(diào)用registerFilters方法來(lái)添加includeFilter(實(shí)際類(lèi)型是:TypeFilter),這個(gè)就是Spring提供的擴(kuò)展點(diǎn),讓咱們自己來(lái)指定需要被掃描的類(lèi),這里使用的是MappScan注解中annotationClass屬性配置的注解類(lèi)型,我們這里配置了Mapper,所以調(diào)用scan方法開(kāi)啟掃描后,Spring就會(huì)將包含Mapper注解的類(lèi)掃描為BeanDefinition。注意這里的掃描能力還是調(diào)用Spring的掃描器來(lái)實(shí)現(xiàn)的,ClassPathMapperScanner并沒(méi)有修改,只是當(dāng)掃描完成后,ClassPathMapperScanner會(huì)對(duì)掃描出的BeanDefinition進(jìn)行重新處理,主要是把原來(lái)的BeanClass修改成了MapperFactoryBean.class:

圖片

而這個(gè)MapperFactoryBean是FactoryBean的實(shí)現(xiàn)類(lèi),老鐵們,F(xiàn)actoryBean這種Bean有什么特點(diǎn)?這個(gè)可是面試的高發(fā)點(diǎn)哦。

做個(gè)小小的總結(jié):Spring掃描到有Mapper注解的類(lèi),生成BeanDefinition,并且將這一類(lèi)BeanDefinition的BeanClass的值修改為MapperFactoryBean,也就是說(shuō)它的類(lèi)型不再是咱們自己編寫(xiě)的Mapper接口了,而是一個(gè)FactoryBean,這樣Spring就能做妖了。

二、Mapper注解的類(lèi)是接口

那如何實(shí)例化呢?

到這一步,其實(shí)老鐵們也大概清楚了,Spring在實(shí)例化Mapper實(shí)例時(shí),實(shí)際上首先會(huì)實(shí)例化MapperFactoryBean,然后再調(diào)用它的getObject方法。我們知道在Java里面接口是肯定不能被實(shí)例化的,那這個(gè)被實(shí)例化的對(duì)象只能是一個(gè)代理對(duì)象,所以我們有理由猜想這個(gè)getObject方法應(yīng)該是用來(lái)創(chuàng)建代理對(duì)象的。要?jiǎng)?chuàng)建代理對(duì)象,得從以下兩個(gè)方面著手:

1.準(zhǔn)備工作

這里Spring準(zhǔn)備的是接口類(lèi)型和創(chuàng)建代理對(duì)象的代理工廠(chǎng)。具體如何準(zhǔn)備的呢?來(lái)看上述MapperFactoryBean類(lèi)型的整體繼承關(guān)系:

圖片

它實(shí)現(xiàn)了InitializingBean,于是可以知道,在MapperFactoryBean初始化完成后,Spring會(huì)調(diào)用它的afterPropertiesSet方法,從而會(huì)執(zhí)行到checkDaoConfig方法:

圖片

在該方法中調(diào)用configuration的addMapper方法,這個(gè)方法里面到底做了啥?

圖片

看出門(mén)道了嗎?其實(shí)就是使用Mapper的接口類(lèi)型作為key,MapperProxyFactory做為value,然后添加到mapperRegistry對(duì)象的Map集合中,注意這個(gè)type同時(shí)也是MapperProxyFactory對(duì)象的構(gòu)造參數(shù)哦。

2.實(shí)例化

上述動(dòng)作已經(jīng)準(zhǔn)備好了,接下來(lái)就應(yīng)該是創(chuàng)建了。Spring在創(chuàng)建完成MapperFactoryBean對(duì)象后,最終會(huì)調(diào)用它的getObject方法來(lái)獲得真實(shí)的對(duì)象:

圖片

圖片

圖片

getObject方法中,會(huì)調(diào)用getMapper方法,該方法中從knowMappers這個(gè)Map集合中拿到MapperProxyFactory對(duì)象,這個(gè)對(duì)象不就是我們?cè)跍?zhǔn)備階段添加的嘛!它就是用來(lái)創(chuàng)建代理對(duì)象的工廠(chǎng)。

圖片

從上面代碼中也不難看出,確實(shí)是為咱們自己的接口創(chuàng)建了代理對(duì)象,而代理類(lèi)的處理類(lèi)則是MapperProxy對(duì)象,也就是說(shuō)對(duì)所有接口對(duì)象的調(diào)用,都會(huì)進(jìn)入MapperProxy的Invoke方法,至此Spring成功對(duì)接MyBatis。

作者介紹

波哥,互聯(lián)行業(yè)從業(yè)10余年,先后擔(dān)任項(xiàng)目總監(jiān)及架構(gòu)師。目前專(zhuān)攻技術(shù),喜歡研究技術(shù)原理。技術(shù)全面,主攻java,精通JVM底層機(jī)制及Spring全家桶底層框架原理,熟練掌握當(dāng)前主流的中間件、服務(wù)網(wǎng)格等技術(shù)原理。

責(zé)任編輯:武曉燕 來(lái)源: 51CTO技術(shù)棧
相關(guān)推薦

2021-11-10 11:37:48

Spring整合 Mybatis

2020-11-09 10:16:41

Mybatis

2018-11-09 09:34:05

面試Spring Clou底層

2024-01-29 08:00:00

架構(gòu)微服務(wù)開(kāi)發(fā)

2023-04-28 08:30:56

MyBatis架構(gòu)API

2017-05-12 15:47:15

Spring BootMybatis Ann Web

2021-08-29 07:41:48

數(shù)據(jù)HashMap底層

2024-06-13 00:54:19

2020-11-05 11:14:29

Docker底層原理

2023-01-04 07:54:03

HashMap底層JDK

2024-01-05 09:00:00

SpringMVC軟件

2021-08-31 07:36:22

LinkedListAndroid數(shù)據(jù)結(jié)構(gòu)

2023-10-18 10:55:55

HashMap

2022-12-19 08:00:00

SpringBootWeb開(kāi)發(fā)

2021-07-05 07:51:43

JVM底層Python

2021-07-23 13:34:50

MySQL存儲(chǔ)InnoDB

2009-06-19 10:00:37

Struts和Spri

2016-12-14 09:03:34

springhibernate異常

2009-06-18 15:24:08

Spring OSGi

2021-01-08 08:34:09

Synchronize線(xiàn)程開(kāi)發(fā)技術(shù)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

主站蜘蛛池模板: 91xxx在线观看 | 日韩在线免费 | 国产一区二区观看 | 在线视频a| av播播 | 狠狠狠色丁香婷婷综合久久五月 | 亚洲最新在线 | www.色五月.com | 久久久久亚洲精品 | 国产激情精品一区二区三区 | 乱码av午夜噜噜噜噜动漫 | 色噜噜狠狠色综合中国 | 日操夜操| 成人在线视频网 | 亚洲一区二区三区免费在线 | 日韩精品久久一区二区三区 | 国产一区不卡 | 一区二区视频 | 粉嫩av久久一区二区三区 | 日韩欧美中文字幕在线视频 | 欧美国产大片 | 在线一区二区观看 | 国产午夜精品一区二区三区嫩草 | 国产精品久久精品 | 国产一区中文字幕 | 日韩三级免费网站 | 久久久免费精品 | 99tv| a视频在线观看 | 亚洲香蕉| 久久久资源| 91精品福利 | 欧美黄色免费网站 | 国产一级一片免费播放 | 一区二区三区在线 | 亚洲色图第一页 | 国产区视频在线观看 | 涩爱av一区二区三区 | 成人免费在线视频 | 亚洲视频二区 | 波多野结衣av中文字幕 |