欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Spring整合Mybatis框架方法剖析

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

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

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

解決的核心問題

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

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

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

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

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

這條由mybatis-spring保證

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

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

3)@Bean 方式,針對每一個接口都要一個@Bean,太麻煩

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

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

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

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

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

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

一級緩存失效問題:

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

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

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

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

invokeBeanFactoryPostProcessors()中整合Mybatis的地方

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

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

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

相關(guān)文章

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

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

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

    Spring Boot 自定義starter的示例代碼

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

    struts2.2.3+spring3.1.0+mybatis3.1.0框架整合集成簡單demo

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

    深入了解Java方法的重載與重寫

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

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

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

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

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

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

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

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

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

    淺談Spring Bean的基本配置

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

    解決阿里云OSS使用URL無法訪問圖片的兩種方法

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

最新評論