Mybatis源码分析——mybatis-config.xml解析

本系列的文章都是基于这个demo来分析的
Mybatis入门,一个简单的demo

在源码分析过程中,会使用到一些额外的知识点,比如
Mybatis中使用的spring接口
Mybatis中使用的设计模式

Mybatis初始化配置文件分为两个阶段,如下

  • mybatis-config.xml解析
  • mapper.xml文件解析

本篇分析的是第一阶段。

首先,看一下初始化入口

	<!-- 配置Mybatis的文件 ,mapperLocations配置**Mapper.xml文件位置,configLocation配置mybatis-config文件位置 -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<property name="dataSource" ref="dataSource" />
		<property name="mapperLocations" value="classpath:mybatis/mapper/*.xml" />
		<property name="configLocation" value="classpath:mybatis/mybatis-config.xml" />
	</bean>

接着,看一下SqlSessionFactoryBeanafterPropertiesSet方法,该方法最终生成一个SqlSessionFactory对象,供后面执行sql时使用。

  @Override
  public void afterPropertiesSet() throws Exception {
    this.sqlSessionFactory = buildSqlSessionFactory();
  }

然后,再看看buildSqlSessionFactory方法,方法中有一个Configuration configuration对象,方法里做的所有事情都是为了初始化这个对象,然后通过SqlSessionFactoryBuilder.build(configuration);返回一个SqlSessionFactory的实例对象DefaultSqlSessionFactory

  protected SqlSessionFactory buildSqlSessionFactory() throws IOException {
    Configuration configuration;
	//省略中间的解析代码
    return this.sqlSessionFactoryBuilder.build(configuration);
  }

接下来,看看是怎么一步一步解析配置文件初始化Configuration configuration的吧。

XMLConfigBuilder xmlConfigBuilder = null;
    if (this.configuration != null) {
		//省略
    } else if (this.configLocation != null) {
      xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
      configuration = xmlConfigBuilder.getConfiguration();
    } else {
		//省略
    }

这里走的是第二个if分支,初始化一个XMLConfigBuilder解析器,并同时初始化一个Configurationnew XMLConfigBuilder()如下

  public XMLConfigBuilder(InputStream inputStream, String environment, Properties props) {
    this(new XPathParser(inputStream, true, props, new XMLMapperEntityResolver()), environment, props);
  }

  private XMLConfigBuilder(XPathParser parser, String environment, Properties props) {
    super(new Configuration());
    ErrorContext.instance().resource("SQL Mapper Configuration");
    this.configuration.setVariables(props);
    this.parsed = false;
    this.environment = environment;
    this.parser = parser;
  }

这里使用XPathParser作为解析器,同时new Configuration(),构造方法里主要是注册一些别名,如下

public Configuration() {
    typeAliasRegistry.registerAlias("JDBC", JdbcTransactionFactory.class);
    typeAliasRegistry.registerAlias("MANAGED", ManagedTransactionFactory.class);

    typeAliasRegistry.registerAlias("JNDI", JndiDataSourceFactory.class);
    typeAliasRegistry.registerAlias("POOLED", PooledDataSourceFactory.class);
    typeAliasRegistry.registerAlias("UNPOOLED", UnpooledDataSourceFactory.class);

    typeAliasRegistry.registerAlias("PERPETUAL", PerpetualCache.class);
    typeAliasRegistry.registerAlias("FIFO", FifoCache.class);
    typeAliasRegistry.registerAlias("LRU", LruCache.class);
    typeAliasRegistry.registerAlias("SOFT", SoftCache.class);
    typeAliasRegistry.registerAlias("WEAK", WeakCache.class);

    typeAliasRegistry.registerAlias("DB_VENDOR", VendorDatabaseIdProvider.class);

    typeAliasRegistry.registerAlias("XML", XMLLanguageDriver.class);
    typeAliasRegistry.registerAlias("RAW", RawLanguageDriver.class);

    typeAliasRegistry.registerAlias("SLF4J", Slf4jImpl.class);
    typeAliasRegistry.registerAlias("COMMONS_LOGGING", JakartaCommonsLoggingImpl.class);
    typeAliasRegistry.registerAlias("LOG4J", Log4jImpl.class);
    typeAliasRegistry.registerAlias("LOG4J2", Log4j2Impl.class);
    typeAliasRegistry.registerAlias("JDK_LOGGING", Jdk14LoggingImpl.class);
    typeAliasRegistry.registerAlias("STDOUT_LOGGING", StdOutImpl.class);
    typeAliasRegistry.registerAlias("NO_LOGGING", NoLoggingImpl.class);

    typeAliasRegistry.registerAlias("CGLIB", CglibProxyFactory.class);
    typeAliasRegistry.registerAlias("JAVASSIST", JavassistProxyFactory.class);
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值