亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

Spring整合Mybatis框架方法剖析

 更新時(shí)間:2023年07月13日 14:02:53   作者:王偵  
這篇文章主要為大家介紹了Spring整合Mybatis框架方法剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

Spring整合其他框架的核心思路

就是將其他框架生成的類放到Spring容器中。同理,Spring整合Mybatis也是讓Mybatis生成的Mapper接口的代理對(duì)象作為Bean注冊(cè)到Spring容器中。

解決的核心問(wèn)題

  • 1)通過(guò)FactoryBean創(chuàng)建Mapper接口代理對(duì)象,并且指定構(gòu)造方法參數(shù)為Mapper接口class,并且設(shè)置BeanDefinition.setAutowireMode(AUTOWIRE_BY_TYPE)。
  • 2)通過(guò)ImportBeanDefinitionRegistrar或者BeanDefinitionRegistryPostProcessor中創(chuàng)建的掃描器實(shí)現(xiàn)對(duì)多個(gè)Mapper接口代理對(duì)象的創(chuàng)建和注冊(cè)。
  • 3)掃描器篩選類時(shí)要重寫(xiě)isCandidateComponent(),第一個(gè)isCandidateComponent()總是返回true(因?yàn)樘砑右粋€(gè)TypeFilter,其match方法總是返回true。),第二個(gè)isCandidateComponent()如果為接口時(shí)返回true。

ClassPathMapperScanner#registerFilters這里面添加一個(gè)總是返回true的TypeFilter:

    if (acceptAllInterfaces) {
      // default include filter that accepts all classes
      addIncludeFilter((metadataReader, metadataReaderFactory) -> true);
    }

關(guān)于Mapper接口生成對(duì)象

  • 1.必須是一個(gè)對(duì)象(代理對(duì)象,JDK動(dòng)態(tài)代理Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy))
  • 2.這個(gè)對(duì)象必須實(shí)現(xiàn)Mapper接口(動(dòng)態(tài)代理對(duì)象必然實(shí)現(xiàn)Mapper接口)
  • 這兩條由mybatis保證
  • 3.必須在spring容器當(dāng)中

這條由mybatis-spring保證

1)FactoryBean,采用的就是這種方式,控制對(duì)象的生成過(guò)程,生成JDK動(dòng)態(tài)代理對(duì)象

2)ac.getBeanFactory().registerSingleton(),也是一樣麻煩

3)@Bean 方式,針對(duì)每一個(gè)接口都要一個(gè)@Bean,太麻煩

4)@Service 這樣是把類交給Spring,然后創(chuàng)建對(duì)象,但是這里是接口,創(chuàng)建對(duì)象會(huì)報(bào)錯(cuò),我們這里需要控制對(duì)象的生成過(guò)程(生成動(dòng)態(tài)代理)

Mybatis-Spring 1.3.2版本底層源碼執(zhí)行流程

  • 1)通過(guò)@MapperScan導(dǎo)入了MapperScannerRegistrar類
  • 2)MapperScannerRegistrar類實(shí)現(xiàn)了ImportBeanDefinitionRegistrar接口,所以Spring在啟動(dòng)時(shí)會(huì)調(diào)用MapperScannerRegistrar類中的registerBeanDefinitions方法
  • 3)在registerBeanDefinitions方法中定義了一個(gè)ClassPathMapperScanner對(duì)象,用來(lái)掃描mapper
  • 4)設(shè)置ClassPathMapperScanner對(duì)象(繼承自ClassPathBeanDefinitionScanner)可以掃描到接口,因?yàn)樵赟pring中是不會(huì)掃描接口的
  • 5)同時(shí)因?yàn)镃lassPathMapperScanner中重寫(xiě)了isCandidateComponent方法,導(dǎo)致isCandidateComponent只會(huì)認(rèn)為接口是備選者Component
  • 6)通過(guò)利用Spring的掃描后,會(huì)把接口掃描出來(lái)并且得到對(duì)應(yīng)的BeanDefinition
  • 7)接下來(lái)把掃描得到的BeanDefinition進(jìn)行修改,把BeanClass修改為MapperFactoryBean,把AutowireMode修改為byType
  • 8)掃描完成后,Spring就會(huì)基于BeanDefinition去創(chuàng)建Bean了,相當(dāng)于每個(gè)Mapper對(duì)應(yīng)一個(gè)FactoryBean
  • 9)在MapperFactoryBean中的getObject方法中,調(diào)用了getSqlSession()去得到一個(gè)sqlSession對(duì)象,然后根據(jù)對(duì)應(yīng)的Mapper接口生成一個(gè)Mapper接口代理對(duì)象,這個(gè)代理對(duì)象就成為Spring容器中的Bean
  • 10)sqlSession對(duì)象是Mybatis中的,一個(gè)sqlSession對(duì)象需要SqlSessionFactory來(lái)產(chǎn)生
  • 11)MapperFactoryBean的AutowireMode為byType,所以Spring會(huì)自動(dòng)調(diào)用set方法,有兩個(gè)set方法,一個(gè)setSqlSessionFactory,一個(gè)setSqlSessionTemplate,而這兩個(gè)方法執(zhí)行的前提是根據(jù)方法參數(shù)類型能找到對(duì)應(yīng)的bean,所以Spring容器中要存在SqlSessionFactory類型的bean或者SqlSessionTemplate類型的bean。
  • 12)如果你定義的是一個(gè)SqlSessionFactory類型的bean,那么最終也會(huì)被包裝為一個(gè)SqlSessionTemplate對(duì)象,并且賦值給sqlSession屬性
  • 13)而在SqlSessionTemplate類中就存在一個(gè)getMapper方法,這個(gè)方法中就產(chǎn)生一個(gè)Mapper接口代理對(duì)象
  • 14)到時(shí)候,當(dāng)執(zhí)行該代理對(duì)象的某個(gè)方法時(shí),就會(huì)進(jìn)入到Mybatis框架的底層執(zhí)行流程

這里注意:SpringManagedTransaction是由SqlSessionFactoryBean引入的。

分析一下Mapper代理對(duì)象執(zhí)行查詢,比如userMapper.selectById(),其底層調(diào)用的是啥?

  • 其實(shí)調(diào)用的是SqlSessionTemplate.selectOne,主要是為了線程安全的,則每個(gè)線程都會(huì)獲取不同的DefaultSqlSession;如果是事務(wù),同一個(gè)線程會(huì)通過(guò)ThreadLocal存儲(chǔ)獲取同一個(gè)DefaultSqlSession(如果不是事務(wù),同一個(gè)線程執(zhí)行不同的sql語(yǔ)句也會(huì)獲取不同的DefaultSqlSession,這樣會(huì)導(dǎo)致一級(jí)緩存失效。一級(jí)緩存生效的前提是:同一個(gè)DefaultSqlSession執(zhí)行多個(gè)相同的sql語(yǔ)句)
  • SqlSessionTemplate會(huì)調(diào)用到SqlSessionProxy.selectOne,SqlSessionProxy的InvocationHandler是SqlSessionInterceptor,在SqlSessionInterceptor#invoke()里面會(huì)getSqlSession()返回一個(gè)SqlSession(這里返回的就是DefaultSqlSession)
  • SqlSessionProxy會(huì)調(diào)用至DefaultSqlSession.selectOne 線程不安全的

一級(jí)緩存失效問(wèn)題:

  • 一般不使用一級(jí)緩存,跟事務(wù)隔離級(jí)別會(huì)沖突。比如讀已提交想要讀取到不同結(jié)果,但是使用緩存后,讀取到的每次都一樣。

Mybatis-Spring 2.0.6版本底層源碼執(zhí)行流程

核心區(qū)別:Mybatis-Spring 1.3.2在MapperScannerRegistrar#registerBeanDefinitions就會(huì)去掃描Mapper接口并生成BD注冊(cè)到Sprign容器。而Mybatis-Spring 2.0.6在MapperScannerRegistrar#registerBeanDefinitions只是注冊(cè)了一個(gè)新的BD:MapperScannerConfigurer,掃描邏輯放到了這個(gè)類中,因?yàn)檫@個(gè)類是一個(gè)BeanDefinitionRegistryPostProcessor。

  • 1)通過(guò)@MapperScan導(dǎo)入了MapperScannerRegistrar類
  • 2)MapperScannerRegistrar類實(shí)現(xiàn)了ImportBeanDefinitionRegistrar接口,所以Spring在啟動(dòng)時(shí)會(huì)調(diào)用MapperScannerRegistrar類中的registerBeanDefinitions方法
  • 3)在registerBeanDefinitions方法中注冊(cè)一個(gè)MapperScannerConfigurer類型的BeanDefinition
  • 4)而MapperScannerConfigurer實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor接口,所以Spring在啟動(dòng)過(guò)程中時(shí)會(huì)調(diào)用它的postProcessBeanDefinitionRegistry()方法
  • 5)在postProcessBeanDefinitionRegistry方法中會(huì)生成一個(gè)ClassPathMapperScanner對(duì)象,然后進(jìn)行掃描
  • 6)后續(xù)的邏輯和1.3.2版本一樣。

invokeBeanFactoryPostProcessors()中整合Mybatis的地方

invokeBeanFactoryPostProcessors()執(zhí)行流程:

  • 1)執(zhí)行通過(guò)ApplicationContext手動(dòng)添加進(jìn)來(lái)的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  • 2)執(zhí)行BeanFactory中實(shí)現(xiàn)了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法。這里會(huì)將ConfigurationClassPostProcessor的BeanDefinition實(shí)例化出來(lái),并進(jìn)行調(diào)用。這里會(huì)處理MapperScannerRegistrar,是個(gè)ImportBeanDefinitionRegistrar。Mybatis-Spring 1.3.2直接在這里掃描,Mybatis-Spring 2.0.6新引入了一個(gè)BeanDefinitionRegistryPostProcessor:MapperScannerConfigurer。
  • 3)執(zhí)行BeanFactory中實(shí)現(xiàn)了Ordered接口的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法
  • 4)執(zhí)行BeanFactory中其他的BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry()方法(這里是個(gè)循環(huán),如果新注冊(cè)了BeanDefinitionRegistryPostProcessor,會(huì)繼續(xù)循環(huán)進(jìn)行處理)。Mybatis-Spring
    2.0.6的MapperScannerConfigurer會(huì)在這里掃描所有Mapper接口并生成BD注冊(cè)到Spring容器。
  • 5)執(zhí)行上面所有的BeanDefinitionRegistryPostProcessor的postProcessBeanFactory()方法
  • 6)執(zhí)行通過(guò)ApplicationContext手動(dòng)添加進(jìn)來(lái)的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  • 7)執(zhí)行BeanFactory中實(shí)現(xiàn)了PriorityOrdered接口的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  • 8)執(zhí)行BeanFactory中實(shí)現(xiàn)了Ordered接口的BeanFactoryPostProcessor的postProcessBeanFactory()方法
  • 9)執(zhí)行BeanFactory中其他的BeanFactoryPostProcessor的postProcessBeanFactory()方法

以上就是Spring整合Mybatis框架源碼剖析的詳細(xì)內(nèi)容,更多關(guān)于Spring整合Mybatis的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • springsecurity實(shí)現(xiàn)用戶登錄認(rèn)證快速使用示例代碼(前后端分離項(xiàng)目)

    springsecurity實(shí)現(xiàn)用戶登錄認(rèn)證快速使用示例代碼(前后端分離項(xiàng)目)

    這篇文章主要介紹了springsecurity實(shí)現(xiàn)用戶登錄認(rèn)證快速使用示例代碼(前后端分離項(xiàng)目),本文通過(guò)示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2024-03-03
  • Spring Boot 自定義starter的示例代碼

    Spring Boot 自定義starter的示例代碼

    這篇文章主要介紹了Spring Boot 自定義starter的示例代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-11-11
  • struts2.2.3+spring3.1.0+mybatis3.1.0框架整合集成簡(jiǎn)單demo

    struts2.2.3+spring3.1.0+mybatis3.1.0框架整合集成簡(jiǎn)單demo

    本篇文章主要介紹了struts2.2.3+spring3.1.0 + mybatis3.1.0框架整合,結(jié)合在一起實(shí)現(xiàn)用戶的增刪改查功能,有需要的可以了解一下。
    2016-11-11
  • 深入了解Java方法的重載與重寫(xiě)

    深入了解Java方法的重載與重寫(xiě)

    在最初學(xué)習(xí)java的時(shí)候,人們都知道,java這種面向?qū)ο蟮恼Z(yǔ)言,一共有三大特征,分別是:封裝、繼承、多態(tài)。多態(tài)的實(shí)現(xiàn)途徑有三種:重寫(xiě)、重載、接口實(shí)現(xiàn)。本文就來(lái)為大家詳細(xì)講講Java方法的重載與重寫(xiě)
    2022-07-07
  • springboot 使用yml配置文件自定義屬性的操作代碼

    springboot 使用yml配置文件自定義屬性的操作代碼

    在SpringBoot中yml/yaml文件可以自定義一些屬性,以供注入給自定義bean對(duì)象的屬性,主要通過(guò)空格和層次來(lái)實(shí)現(xiàn),類似于python代碼,本文通過(guò)實(shí)例代碼給大家介紹springboot 使用yml配置文件自定義屬性,感興趣的朋友跟隨小編一起看看吧
    2024-03-03
  • 關(guān)于@ComponentScan?TypeFilter自定義指定掃描bean的規(guī)則

    關(guān)于@ComponentScan?TypeFilter自定義指定掃描bean的規(guī)則

    這篇文章主要介紹了關(guān)于@ComponentScan?TypeFilter自定義指定掃描bean的規(guī)則,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-09-09
  • mybatis-plus如何修改日志只打印SQL語(yǔ)句不打印查詢結(jié)果

    mybatis-plus如何修改日志只打印SQL語(yǔ)句不打印查詢結(jié)果

    這篇文章主要介紹了mybatis-plus如何修改日志只打印SQL語(yǔ)句不打印查詢結(jié)果問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-06-06
  • Java出現(xiàn)中文亂碼問(wèn)題分析及解決方案

    Java出現(xiàn)中文亂碼問(wèn)題分析及解決方案

    在Java開(kāi)發(fā)中,處理中文亂碼是一個(gè)常見(jiàn)的問(wèn)題,由于字符集和編碼的復(fù)雜性,開(kāi)發(fā)者可能面臨各種導(dǎo)致亂碼的情況,正確地處理中文字符集對(duì)于確保應(yīng)用程序的可靠性和國(guó)際化至關(guān)重要,本文給大家介紹了Java中文亂碼分析及解決方案,需要的朋友可以參考下
    2024-02-02
  • 淺談Spring Bean的基本配置

    淺談Spring Bean的基本配置

    這篇文章主要介紹了淺談Spring Bean的基本配置,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)java Spring的小伙伴們有非常好的幫助,需要的朋友可以參考下
    2021-05-05
  • 解決阿里云OSS使用URL無(wú)法訪問(wèn)圖片的兩種方法

    解決阿里云OSS使用URL無(wú)法訪問(wèn)圖片的兩種方法

    這篇文章主要介紹了解決阿里云OSS使用URL無(wú)法訪問(wèn)圖片的兩種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-08-08

最新評(píng)論