mybatis源碼分析(1)-----sqlSessionFactory創建


1. 首先了解一下mybatis,包含核心jar ,以及spring相關jar.

<!-- Mybatis相關組件 -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.3.0</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.3</version>
</dependency>
  • 系列的文章也是mybatis 3.3.0和mybatis-spring1.2.3分析
  • mybatis jar包中只要包含mybaits的核心業務sqlsession,sqlsessionFactory,configuration
  • mybatis-spring 包中只要是和spring的相關集成,sqlSessionFactoryBean、transaction

 

2. 加載mybatis

本文以spring中加載mybatis為參考,由一下代碼加載mybatis

<!-- 配置集成Mybatis -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
    <property name="dataSource" ref="dataSource" />
    <property name="configLocation" value="classpath:/config/SQLMapConfig.xml" />
    <property name="mapperLocations"
        value="classpath*:com/chihiro/*/**/infra/mybatis/*Mapper.xml" />
</bean>

 

  • sqlSessionFactory接口(mybatis包核心接口)

  a、接口中有如下方法。子類中含有所有方法的實現

public interface SqlSessionFactory {
  SqlSession openSession();
  SqlSession openSession(boolean autoCommit);
  SqlSession openSession(Connection connection);
  SqlSession openSession(TransactionIsolationLevel level);
  SqlSession openSession(ExecutorType execType);
  SqlSession openSession(ExecutorType execType, boolean autoCommit);
  SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
  SqlSession openSession(ExecutorType execType, Connection connection);
  Configuration getConfiguration();
}

  b、接口的實現類,由sqlSessionFactoryBean產生的是默認的SqlSessionFactory(DefaultSqlSessionFactory)

  

 

  •  sqlSessionFactoryBean(mybatis-spring包下面的創建工廠的Bean,由spring 加載初始化)

  a、從上述mybais的加載,可以看到,構造sqlSessionFactoryBean之后給了默認的屬性值,dataSource,configLocation,mapper

public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> {

  private static final Log LOGGER = LogFactory.getLog(SqlSessionFactoryBean.class);

  private Resource configLocation;

  private Resource[] mapperLocations;

  private DataSource dataSource;

  //SqlSessionFactory 構造的協助類
  private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

  private SqlSessionFactory sqlSessionFactory;

  //創建sqlSessionFactory的方法體
  protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
      Configuration configuration;
      XMLConfigBuilder xmlConfigBuilder = null;
      if (this.configLocation != null) {
    xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
    configuration = xmlConfigBuilder.getConfiguration();
    } else {
      if (LOGGER.isDebugEnabled()) {
        LOGGER.debug("Property 'configLocation' not specified, using default MyBatis Configuration");
      }
      configuration = new Configuration();
      configuration.setVariables(this.configurationProperties);
    }
    ...
    return this.sqlSessionFactoryBuilder.build(configuration);
  }ss

  @Override
  public void afterPropertiesSet() throws Exception {
    notNull(dataSource, "Property 'dataSource' is required");
    notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
    //調用方法創建sqlSessionFactory
    this.sqlSessionFactory = buildSqlSessionFactory();
  }

  @Override
  public void onApplicationEvent(ApplicationEvent event) {
    if (failFast && event instanceof ContextRefreshedEvent) {
      // fail-fast -> check all statements are completed
      this.sqlSessionFactory.getConfiguration().getMappedStatementNames();
    }
  }

}

 

  1. 實現3個相關接口的作用

    FactoryBean接口:實現了該接口的類,在調用getBean(獲取bean對象)的時候會返回該工廠返回的實例對象,也就是再調一次getObject方法返回工廠的實例。

    InitializingBean接口:實現了這個接口,那么當bean初始化的時候,spring就會調用該接口的實現類的afterPropertiesSet方法,去實現當spring初始化該Bean的時候所需要的邏輯。

    ApplicationListener接口:實現了該接口,如果注冊了該監聽的話,那么就可以了監聽到Spring的一些事件,然后做相應的處理

     2.在bean初始化之后,可以看見,回調方法afterPropertiesSet,在里面構造configuration對象。以及產生sqlSession

    Configuration類:可以發現配置中讀取configuration。(核心配置,關聯mybatis整個生命周期)

      xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
      configuration = xmlConfigBuilder.getConfiguration();

    3.由sqlSessionFactoryBuild 構造sqlSessionFactory

public class SqlSessionFactoryBuilder {
    
  public SqlSessionFactory build(Configuration config) {
    return new DefaultSqlSessionFactory(config);
  }

}

 

4. 建設者模式

  生產sqlSessionFacoty 使用了建設者模式(Builder)。其構造過程主要注入了Configuration的實例對象,sqlSessionFactoryBuilder 扮演具體的建造者,configuration類主要負責建造細節的工作,sqlSessionFactory則是建造出來的產品

 

 

  •   總結

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM