乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Mybatis源碼分析(四):屬性接口之configLocation

       云夢(mèng)天涯rqxe9h 2018-02-14

      上節(jié)內(nèi)容我們了解了SqlSessionFactoryBean所有暴露出來(lái)的屬性,方便用戶(hù)通過(guò)配置對(duì)mybatis擴(kuò)展!今天我們一起看看configLocation源碼!

       

      對(duì)configLocation進(jìn)行源碼分析我就的知道這個(gè)屬性在spring和mybatis整合的時(shí)候怎么使用!

      一.configLocation如何使用

      Spring核心配置文件中的配置如下(SqlSessionFactoryBean配置configLocation屬性,去加載mybatis的config配置文件

      'sqlSessionFactory' class='org.mybatis.spring.SqlSessionFactoryBean'>
         property name='dataSource' ref='dataSource' />
         
         property name='configLocation'>
           value>classpath:sqlMapConfig.xmlvalue>
         property>
      bean>


      sqlMapConfig.xml

      <>xml version='1.0' encoding='UTF-8' ?>  
      PUBLIC '-////DTD Config 3.0//EN'  
      'http:///dtd/mybatis-3-config.dtd'>
       
      configuration>  
       typeAliases>
          typeAlias type='com.zzy.model.User' alias='User' />
       typeAliases>
       mappers>
          mapper resource='com/zzy/xml/UserMapper.xml' />
       mappers>
       
      configuration>


      這里標(biāo)簽屬性實(shí)際上和上節(jié)SqlSessionFactoryBean  下屬性是一致的。暫時(shí)不做詳細(xì)配置?。ㄒ簿褪强梢园裇qlSessionFactoryBean下屬性全部配置到mybatis配置文件中)


      二.源碼分析過(guò)程

      1.configLocation 的入口源碼


      先看這個(gè)屬性被mybatis讀取位置的源碼


      SqlSessionFactoryBean  >> buildSqlSessionFactory

      XMLConfigBuilder xmlConfigBuilder = null;
         if (this.configuration != null) {
           configuration = this.configuration;
           if (configuration.getVariables() == null) {
             configuration.setVariables(this.configurationProperties);
           } else if (this.configurationProperties != null) {
             configuration.getVariables().putAll(this.configurationProperties);
           }
         } else if (this.configLocation != null) {
           xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
           configuration = xmlConfigBuilder.getConfiguration();
         } else {
           if (LOGGER.isDebugEnabled()) {
             LOGGER.debug('Property 'configuration' or 'configLocation' not specified, using default MyBatis Configuration');
           }
           configuration = new Configuration();
           if (this.configurationProperties != null) {
             configuration.setVariables(this.configurationProperties);
           }
         }


      上述代碼含義Mybatis初始化的過(guò)程,首先看configuration是否為空,初始化之前這個(gè)對(duì)象是為空的。


      然后就是看是否配置了configLocation 。


      如果配置了,會(huì)將configLocation包裝成一個(gè)xmlConfigBuilder對(duì)象。


      有必要先說(shuō)明下org.apache.ibatis.session.Configuration

      和org.apache.ibatis.builder.xml.XMLConfigBuilder這兩個(gè)類(lèi)

       

      Configuration:

      mybatis的一個(gè)數(shù)據(jù)管家,里面存在了,只要mybatis執(zhí)行過(guò)程中用到的各種數(shù)據(jù)都在,例如:mapper文件路徑、別名數(shù)據(jù)、解析出來(lái)的sql語(yǔ)句、結(jié)果集數(shù)據(jù)等)這個(gè)類(lèi)在mybatis框架中比較總要的一個(gè)類(lèi),下期著重講!

       

      XMLConfigBuilder:

      public class XMLConfigBuilder extends BaseBuilder

      用來(lái)解析mybatis的全局配置文件sqlMapConfig.xml的,這個(gè)類(lèi)繼承自父類(lèi)BaseBuilder,父類(lèi)中有個(gè)很重要的方法parse(代碼如下:

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


      2.xmlConfigBuilder 解析sqlMapConfig.xml過(guò)程


      a.

      上面sqlMapConfig.xml被讀取到后,創(chuàng)建了xmlConfigBuilder對(duì)象,然后是用xmlConfigBuilder中的方法解析xml文件,繼續(xù)看buildSqlSessionFactory這個(gè)方法。xml解析的位置在這個(gè)方法中靠下的位置有如下代碼:


      if (xmlConfigBuilder != null) {
           try {
             xmlConfigBuilder.parse();

             if (LOGGER.isDebugEnabled()) {
               LOGGER.debug('Parsed configuration file: '' + this.configLocation + ''');
             }
           } catch (Exception ex) {
             throw new NestedIOException('Failed to parse config resource: ' + this.configLocation, ex);
           } finally {
             ErrorContext.instance().reset();
           }
         }


      xmlConfigBuilder.parse();就是解析讀取到的mybatis配置文件

      sqlMapConfig.xml。


      b.

      XmlConfigBuilder 的parse方法源碼:


      public Configuration parse() {
         if (parsed) {
           throw new BuilderException('Each XMLConfigBuilder can only be used once.');
         }
         parsed = true;
         parseConfiguration(parser.evalNode('/configuration'));
         return configuration;
       }

      其中parseConfiguration(parser.evalNode('/configuration'));

      這段代碼簡(jiǎn)單說(shuō)下,parseConfiguration深入解析的方法。

       

      parser.evalNode('/configuration')屬于XPath 語(yǔ)法【自己復(fù)習(xí)】,這個(gè)地方的含義就是選取configuration為根節(jié)點(diǎn),我們可以看到

      parser.evalNode('/configuration')返回值是

      sqlMapConfig.xml文件中configuration就是根節(jié)點(diǎn),獲取到

      configuration根節(jié)點(diǎn)的全部信息,斷點(diǎn)截圖如下:

      c.

      parseConfiguration() 源碼如下:

      private void parseConfiguration(XNode root) {
         try {
           //issue #117 read properties first
           propertiesElement(root.evalNode('properties'));
           Properties settings = settingsAsProperties(root.evalNode('settings'));
           loadCustomVfs(settings);
           typeAliasesElement(root.evalNode('typeAliases'));
           pluginElement(root.evalNode('plugins'));
           objectFactoryElement(root.evalNode('objectFactory'));
           objectWrapperFactoryElement(root.evalNode('objectWrapperFactory'));
           reflectorFactoryElement(root.evalNode('reflectorFactory'));
           settingsElement(settings);
           // read it after objectFactory and objectWrapperFactory issue #631
           environmentsElement(root.evalNode('environments'));
           databaseIdProviderElement(root.evalNode('databaseIdProvider'));
           typeHandlerElement(root.evalNode('typeHandlers'));
           mapperElement(root.evalNode('mappers'));
         } catch (Exception e) {
           throw new BuilderException('Error parsing SQL Mapper Configuration. Cause: ' + e, e);
         }
       }


      上面代碼就是對(duì)sqlMapConfig.xml文件中的標(biāo)簽依次讀取(就是上節(jié)講到的mybatis所暴露出的所有接口)Mybatis源碼分析(三):Mybatis所有暴露的接口及其作用。


      舉兩個(gè)元素解讀的例子:xml文件中兩個(gè)標(biāo)簽(typeAliasesmappers)的解析方法

        typeAliasesElement(root.evalNode('typeAliases'));

        mapperElement(root.evalNode('mappers'));

       

      簡(jiǎn)單說(shuō)明下typeAliases標(biāo)簽的解析過(guò)程,除去mappers標(biāo)簽之外,其他標(biāo)簽就不做詳細(xì)解讀(類(lèi)似typeAliases)。

      typeAliases標(biāo)簽的解析過(guò)程源碼如下:


      private void typeAliasesElement(XNode parent) {
         if (parent != null) {
           for (XNode child : parent.getChildren()) {
             if ('package'.equals(child.getName())) {
               String typeAliasPackage = child.getStringAttribute('name');
               configuration.getTypeAliasRegistry().registerAliases(typeAliasPackage);
             } else {
               String alias = child.getStringAttribute('alias');
               String type = child.getStringAttribute('type');
               try {
                 Class clazz = Resources.classForName(type);
                 if (alias == null) {
                   typeAliasRegistry.registerAlias(clazz);
                 } else {
                   typeAliasRegistry.registerAlias(alias, clazz);
                 }
               } catch (ClassNotFoundException e) {
                 throw new BuilderException('Error registering typeAlias for '' + alias + ''. Cause: ' + e, e);
               }
             }
           }
         }
       }


      上面整個(gè)過(guò)程就是對(duì)typeAlias type='com.zzy.model.User' alias='User' />解析的過(guò)程

      上面代碼中我們可以看到一個(gè)對(duì)象typeAliasRegistry,這個(gè)對(duì)象反射類(lèi)是

      TypeAliasRegistry,這個(gè)類(lèi)是用來(lái)包裝別名存在的map

       

      簡(jiǎn)單看看TypeAliasRegistry.class:

      public class TypeAliasRegistry {

       private final MapString, Class> TYPE_ALIASES = new HashMapString, Class>();



      其中TYPE_ALIASES存放別名對(duì)應(yīng)關(guān)系的一個(gè)map,這個(gè)map又被typeAliasRegistry封裝。

       

      上面代碼typeAliasRegistry.registerAlias(alias, clazz)就是講type和alias的對(duì)應(yīng)關(guān)系注冊(cè)到typeAliasRegistry對(duì)象的map中!

       

      以上所有的操作過(guò)程都在XMLConfigBuilder中,在XMLConfigBuilder父類(lèi)BaseBuilder中有這樣一段代碼

      this.typeAliasRegistry = this.configuration.getTypeAliasRegistry();


      最后typeAliasRegistry 別名對(duì)象還是被放到大數(shù)據(jù)管家configuration中了(下節(jié)分析configuration),驗(yàn)證了我們上面說(shuō)的configuration包含mybatis所需的各種數(shù)據(jù)。


      d.

       mapperElement(root.evalNode('mappers'))源碼中截取重要的一段


      if (resource != null && url == null && mapperClass == null) {
                 ErrorContext.instance().resource(resource);
                 InputStream inputStream = Resources.getResourceAsStream(resource);
                 XMLMapperBuilder mapperParser = new XMLMapperBuilder(inputStream, configuration, resource, configuration.getSqlFragments());
                 mapperParser.parse();
               }



      關(guān)鍵方法 mapperParser.parse()代碼:

      public void parse() {
         if (!configuration.isResourceLoaded(resource)) {
           configurationElement(parser.evalNode('/mapper'));
           configuration.addLoadedResource(resource);
           bindMapperForNamespace();
         }

         parsePendingResultMaps();
         parsePendingChacheRefs();
         parsePendingStatements();
       }


      這個(gè)方法是對(duì)Mapper.xml文件中增刪改查標(biāo)簽解析的過(guò)程。


      多說(shuō)一句,通過(guò)mapperLocation這個(gè)屬性配置Mapper.xml文件,解析Mapper.xml也會(huì)回到上面方法中(后期分析mapperLocation屬性接口的

      時(shí)候會(huì)通過(guò)源碼看到)

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶(hù)發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買(mǎi)等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶(hù) 評(píng)論公約

        類(lèi)似文章 更多