mybatis源碼分析:從SqlSessionFactory到代理對象的生成

2020-12-08 計算機java編程

根據XML配置文件構建SqlSessionFactory

1. 首先讀取類路徑下的配置文件,獲取其字節輸入流。

2. 創建SqlSessionFactoryBuilder對象,調用內部的build方法。factory = new SqlSessionFactoryBuilder().build(in);

3. 根據字節輸入流創建XMLConfigBuilder即解析器對象parser。

XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);

4. 調用parser對象的parse方法,parser.parse(),該結果將返回一個Configuration配置對象,作為build方法的參數。

5. parse()方法中,調用parseConfiguration方法將Configuration元素下的所有配置信息封裝進Parser對象的成員Configuration對象之中。

6. 其中進行解析xml元素的方式是將通過evalNode方法獲取對應名稱的節點信息。如:parseConfiguration(parser.evalNode("/configuration"));,此時parser.evalNode("/configuration")即為Configuration下的所有信息。

7. parseConfiguration方法相當於將裡面每個元素的信息都單獨封裝到Configuration中。

值得一提的是,我們之後要分析基於代理模式產生dao的代理對象涉及到mappers的封裝,其實也在配置文件讀取封裝的時候就已經完成,也就是在parseConfiguration方法之中:mapperElement(root.evalNode("mappers"));。他的作用就是,讀取我們主配置文件中<mappers>的元素內容,也就是我們配置的映射配置文件。

private void mapperElement(XNode parent)方法將mappers配置下的信息獲取,此處獲取我們resources包下的com.smday.dao包名。

接著就調用了configuration的addMappers方法,其實還是調用的是mapperRegistry。

讀到這裡,我們就會漸漸了解MapperRegistry這個類的職責所在,接著來看,這個類中進行的一些工作,在每次添加mappers的時候,會利用ResolverUtil類查找類路徑下的該包名路徑下,是否有滿足條件的類,如果有的話,就將Class對象添加進去,否則報錯。

緊接著,就到了一步比較重要的部分,當然只是我個人覺得,因為第一遍看的時候,我沒有想到,這步居然可以封裝許許多多的重要信息,我們來看一看:

映射配置文件的讀取依靠namespace,我們可以通過查看源碼發現讀取映射配置文件的方法是loadXmlResouce(),所以namespace命名空間至關重要:

可以看到,對映射文件解析之後,mappedStatements對象中出現了以下內容:

至此,主配置文件和映射配置文件的配置信息就已經讀取完畢。

8. 最後依據獲得的Configuration對象,創建一個new DefaultSqlSessionFactory(config)。

總結:

解析配置文件的信息,並保存在Configuration對象中。返回包含Configuration的DefaultSqlSession對象。通過SqlSessionFactory創建SqlSession

1. 調用SqlSessionFactory對象的openSession方法,其實是調用

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit)

方法,通過參數就可以知道,分別是執行器的類型,事務隔離級別和設置是否自動提交,因此,我們就可以得知,我們在創建SqlSession的時候可以指定這些屬性。

2. 從configuration中獲取environment、dataSource和transactionFactory信息,創建事務對象Transaction。

補充:後續看了一些博客,說是保證executor不為空,因為defaultExecutorType有可能為空。

3. 根據配置信息,執行器信息和自動提交信息創建DefaultSqlSession。

getMapper獲取動態代理對象

下面這句話意思非常明了,就是通過傳入接口類型對象,獲取接口代理對象。

IUserDao userDao1 = sqlSession1.getMapper(IUserDao.class);

具體的過程如下:

1. 首先,調用SqlSession的實現類DefaultSqlSession的getMapper方法,其實是在該方法內調用configuration的getMapper方法,將接口類對象以及當前sqlsession對象傳入。

2. 接著調用我們熟悉的mapperRegistry,因為我們知道,在讀取配置文件,創建sqlSession的時候,接口類型信息就已經被存入到其內部維護的Map之中。

3. 我們來看看getMapper方法具體的實現如何:

4. 緊接著,我們進入MapperProxyFactory,真真實實地發現了創建代理對象的過程。

相關焦點

  • mybatis中SqlSessionFactory類創建過程
    上一篇介紹了mybatis源碼環境的搭建,今天就來開始看源碼。mybatis執行主要流程上一篇文章中介紹的mybatis源碼環境中的測試代碼如下圖:可以看到可mybatis相關的實際上就只有三步:創建SqlSessionFactory、通過SqlSessionFactory創建SqlSession、SqlSession
  • 看到Mybatis源碼就感到煩躁,怎麼辦?
    Mybatis源碼分析今天,我們就來看看Mybatis源碼的閱讀,具體舉個例子來看看:案例和疑問從我們最初的demo中開始:publicstaticvoidmain(String[] args) {包括mybatis-config.xml和我們的Mapper.xml映射器文件。這一步我們關心的內容是:解析的時候做了什麼?產生了什麼對象,解析的結果放在哪裡的。因為這將意味著,我們後面使用的時候去哪裡獲取這項配置項內容。第二步,通過SqlSessionFactory創建一個SqlSession。
  • 從0 開始手寫一個 Mybatis 框架,三步搞定!
    MyBatis框架的核心功能其實不難,無非就是動態代理和jdbc的操作,難的是寫出來可擴展,高內聚,低耦合的規範的代碼。本文完成的Mybatis功能比較簡單,代碼還有許多需要改進的地方,大家可以結合Mybatis源碼去動手完善。
  • 重學Java 設計模式:實戰代理模式「模擬mybatis-spring中定義DAO...
    四、案例場景模擬場景模擬;實現mybatis-spring中代理類生成部分「在本案例中我們模擬實現mybatis-spring中代理類生成部分」對於Mybatis的使用中只需要定義接口不需要寫實現類就可以完成增刪改查操作,有疑問的小夥伴,在本章節中就可以學習到這部分知識。
  • Mybatis中mapper的xml解析詳解
    基礎介紹回顧下之前是在分析configuration的初始化過程,已經進行到了最後一步mapperElement(root.evalNode("mappers")),這個方法裡有兩種解析mapper的方法,一種是解析類,一種是解析xml文件,上一篇文章在講解析類中的註解,今天說到的就是解析xml
  • MyBatis JPA Extra,MyBatis JPA 擴展 v2.2 發布
    MyBatis JPA ExtraMyBatis JPA Extra對MyBatis進行了JPA擴展,旨在基於JPA 2.1的注釋簡化對單表CUID操作,根據JPA注釋動態生成相關資源MyBatis網站MyBatis GitHub源碼1、JavaBean注釋簡單只支持6個注釋 @Entity @Table @Column @Id @GeneratedValue @
  • Mybatis中SqlSource解析流程詳解
    前面幾篇文章都在詳細分析mapper的加載過程,但是始終沒有看到sql的解析過程,今天來詳細分析下。解析sql的位置前面分析到不管是通過註解還是通過xml方式生成mapper,最終都是調用MapperBuilderAssistant類的addMappedStatement方法,這個方法接受的其中一個SqlSource參數,SqlSource類中就是XML文件或者註解方法中映射語句的實現
  • 徹底搞懂MyBatis插件原理及PageHelper原理
    return invocation.proceed();//調用原方法 }@Overridepublic Object plugin(Object target){return Plugin.wrap(target,this);//把被攔截對象生成一個代理對象
  • 面試官問你MyBatis SQL是如何執行的?把這篇文章甩給他
    具體來看一下這個過程在 SqlSessionFactory.openSession 過程中我們可以看到,會調用到 DefaultSqlSessionFactory 中的openSessionFromDataSource方法,這個方法主要創建了兩個與我們分析執行流程重要的對象,一個是Executor執行器對象,一個是SqlSession對象。
  • 面試官:Mybatis 使用了哪些設計模式?
    本文轉載自【微信公眾號:java進階架構師,ID:java_jiagoushi】經微信公眾號授權轉載,如需轉載與原文作者聯繫雖然我們都知道有20多個設計模式,但是大多停留在概念層面,真實開發中很少遇到,Mybatis源碼中使用了大量的設計模式,閱讀源碼並觀察設計模式在其中的應用,能夠更深入的理解設計模式。
  • 小學妹問:Mybatis常見註解有哪些?
    該註解是由Mybatis框架中定義的一個描述數據層接口的註解,註解往往起到的都是一個描述性作用,用於告訴Spring框架此接口的實現類由Mybatis負責創建,並將其實現類對象存儲到spring容器中。
  • SpringBoot + MyBatis + MySQL讀寫分離實踐!
    第一種是依靠中間件(比如:MyCat),也就是說應用程式連接到中間件,中間件幫我們做SQL分離;第二種是應用程式自己去做分離。--<plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId>
  • 001|搭上SpringBoot自動注入源碼分析專車
    專車介紹該趟專車是開往Spring Boot自動注入原理源碼分析的專車專車問題Spring Boot何時注入@Autowired標註的屬性?接下來我們就開始對源碼進行分析專車分析在分析代碼之前我們先回憶一下操作對象的步驟:首先我們會實例化一個對象然後調用對象的set方法來設置對象的屬性有了上面的基礎知識
  • springmvc攔截器及源碼分析
    本案例來演示一個較簡單的springmvc攔截器的使用,並通過分析源碼來探究攔截器的執行順序是如何控制的。-- 配置初始化參數,創建完DispatcherServlet對象,加載springmvc.xml配置文件 --><init-param><param-name>contextConfigLocation</param-name><param-value
  • 乾貨|新手也能看懂的源碼閱讀技巧
    :【原創】001 | 搭上 SpringBoot 自動注入源碼分析專車【原創】002 | 搭上 SpringBoot 事務源碼分析專車【原創】003 | 搭上基於 SpringBoot 事務思想實戰專車
  • 「精品源碼分享」springboot開發的學校教務管理系統
    前言大家好,我是it分享師,今天給大家帶來一個基於Springboot開發的精緻的學校教務管理系統的源碼!如果覺得本文對您有用的話,點讚,轉發,關注三連,私信我獲取源碼!創作不易,謝謝支持!使用技術該系統使用了springboot+mybatis+layui+shiro+jquery等技術開發而成有3個基本角色,為管理員,老師和學生!管理員具有這些模塊的所有功能!老師具有課程管理,成績管理,學生管理等功能!學生有選課管理等功能!基本實現了學校學生選課的一個後臺管理系統!
  • Spring源碼解析之源碼的下載編譯
    老粉應該知道了,筆者最近剛上架技術生涯的第一本書《Java源碼模擬面試解析指南 》。於是趁著年輕時還有時間修福報,準備再做一個 Spring源碼面試指南。相比於之前是直接閱讀引入jar包的方式來研讀 JDK 源碼,由於框架源碼的複雜性及強可插拔性,一般將源碼編譯到本地,由此便可以邊研讀源碼邊加自由地注釋,方便調試程序等。首先進入 spring 官方倉庫,fork 一份倉庫到自己帳號下,方便自己提交。
  • 前端如何一鍵生成多維度數據可視化分析報表
    , 導出excel部分我們已經在上篇文章介紹過了, 這裡我們會詳細分析生成分析報告功能.基於數據一鍵生成多維度數據可視化分析報表解決方案上面介紹了可度量緯度的概念, 這一章節我們就來實現如何計算可度量緯度.
  • Mybatis緩存體系結構
    因此,我將首先會向大家介紹 Cache 幾種實現類的源碼,然後再分析一級和二級緩存的實現。本文主要內容:Mybatis緩存體系結構Mybatis跟緩存相關的類都在cache包目錄下,在前面的文章中我們也提過,今天才來詳細說說。