• mybatis的sqlSessionFactory的加载过程


    使用过SSM的框架的都知道mybatis这个持久层框架,今天小编就来简单说说这个框架的核心工厂类sqlSessionFactory的加载过程,一般的SSM框架我们都会在spring的application.xml中引入如下的配置:

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
            <property name="dataSource" ref="dataSource"></property>
            <property name="configLocation" value="classpath:config/mybatis-config.xml"></property>
        </bean>

    其中的SqlSessionFactoryBean便是加载sqlSessionFactory的入口,首先我们来看看这个类的源代码:

    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;
    
     private TransactionFactory transactionFactory;
    
      private Properties configurationProperties;
    
      private SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    
      private SqlSessionFactory sqlSessionFactory;

    其中标红的两处,就是我们在application.xml中注入的两个属性,从源码中我们可以看出该类实现了InitializingBean接口,实现了其afterPropertiesSet()方法,

    该方法是在当前bean的所有属性被初始化完成之后再执行,也就是其中的datasource和configurationProperties等属性,接下来我们看看这个方法主要干什么了?

    1 public void afterPropertiesSet() throws Exception {
    2     notNull(dataSource, "Property 'dataSource' is required");
    3     notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
    4 
    5     this.sqlSessionFactory = buildSqlSessionFactory();
    6   }

    其中第5行很明显的buildSqlSessionFactory()方法初始化了sqlSessionFactory ,接下来我们看看这个方法的主要行为:

      1 Configuration configuration;
      2 
      3     XMLConfigBuilder xmlConfigBuilder = null;
      4     if (this.configLocation != null) {
      5       xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
      6       configuration = xmlConfigBuilder.getConfiguration();
      7     } else {
      8       if (logger.isDebugEnabled()) {
      9         logger.debug("Property 'configLocation' not specified, using default MyBatis Configuration");
     10       }
     11       configuration = new Configuration();
     12       configuration.setVariables(this.configurationProperties);
     13     }
     14 
     15     if (this.objectFactory != null) {
     16       configuration.setObjectFactory(this.objectFactory);
     17     }
     18 
     19     if (this.objectWrapperFactory != null) {
     20       configuration.setObjectWrapperFactory(this.objectWrapperFactory);
     21     }
     22 
     23     if (hasLength(this.typeAliasesPackage)) {
     24       String[] typeAliasPackageArray = tokenizeToStringArray(this.typeAliasesPackage,
     25           ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
     26       for (String packageToScan : typeAliasPackageArray) {
     27         configuration.getTypeAliasRegistry().registerAliases(packageToScan,
     28                 typeAliasesSuperType == null ? Object.class : typeAliasesSuperType);
     29         if (logger.isDebugEnabled()) {
     30           logger.debug("Scanned package: '" + packageToScan + "' for aliases");
     31         }
     32       }
     33     }
     34 
     35     if (!isEmpty(this.typeAliases)) {
     36       for (Class<?> typeAlias : this.typeAliases) {
     37         configuration.getTypeAliasRegistry().registerAlias(typeAlias);
     38         if (logger.isDebugEnabled()) {
     39           logger.debug("Registered type alias: '" + typeAlias + "'");
     40         }
     41       }
     42     }
     43 
     44     if (!isEmpty(this.plugins)) {
     45       for (Interceptor plugin : this.plugins) {
     46         configuration.addInterceptor(plugin);
     47         if (logger.isDebugEnabled()) {
     48           logger.debug("Registered plugin: '" + plugin + "'");
     49         }
     50       }
     51     }
     52 
     53     if (hasLength(this.typeHandlersPackage)) {
     54       String[] typeHandlersPackageArray = tokenizeToStringArray(this.typeHandlersPackage,
     55           ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
     56       for (String packageToScan : typeHandlersPackageArray) {
     57         configuration.getTypeHandlerRegistry().register(packageToScan);
     58         if (logger.isDebugEnabled()) {
     59           logger.debug("Scanned package: '" + packageToScan + "' for type handlers");
     60         }
     61       }
     62     }
     63 
     64     if (!isEmpty(this.typeHandlers)) {
     65       for (TypeHandler<?> typeHandler : this.typeHandlers) {
     66         configuration.getTypeHandlerRegistry().register(typeHandler);
     67         if (logger.isDebugEnabled()) {
     68           logger.debug("Registered type handler: '" + typeHandler + "'");
     69         }
     70       }
     71     }
     72 
     73     if (xmlConfigBuilder != null) {
     74       try {
     75         xmlConfigBuilder.parse();
     76 
     77         if (logger.isDebugEnabled()) {
     78           logger.debug("Parsed configuration file: '" + this.configLocation + "'");
     79         }
     80       } catch (Exception ex) {
     81         throw new NestedIOException("Failed to parse config resource: " + this.configLocation, ex);
     82       } finally {
     83         ErrorContext.instance().reset();
     84       }
     85     }
     86 
     87     if (this.transactionFactory == null) {
     88       this.transactionFactory = new SpringManagedTransactionFactory();
     89     }
     90 
     91     Environment environment = new Environment(this.environment, this.transactionFactory, this.dataSource);
     92     configuration.setEnvironment(environment);
     93 
     94     if (this.databaseIdProvider != null) {
     95       try {
     96         configuration.setDatabaseId(this.databaseIdProvider.getDatabaseId(this.dataSource));
     97       } catch (SQLException e) {
     98         throw new NestedIOException("Failed getting a databaseId", e);
     99       }
    100     }
    101 
    102     if (!isEmpty(this.mapperLocations)) {
    103       for (Resource mapperLocation : this.mapperLocations) {
    104         if (mapperLocation == null) {
    105           continue;
    106         }
    107 
    108         try {
    109           XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
    110               configuration, mapperLocation.toString(), configuration.getSqlFragments());
    111           xmlMapperBuilder.parse();
    112         } catch (Exception e) {
    113           throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
    114         } finally {
    115           ErrorContext.instance().reset();
    116         }
    117 
    118         if (logger.isDebugEnabled()) {
    119           logger.debug("Parsed mapper file: '" + mapperLocation + "'");
    120         }
    121       }
    122     } else {
    123       if (logger.isDebugEnabled()) {
    124         logger.debug("Property 'mapperLocations' was not specified or no matching resources found");
    125       }
    126     }
    View Code

    该方法主要就是设置configuration参数,首先是从mybatis-config.xml中获取对应的配置信息,然后再从spring的注入属性中获取所有的配置信息,从后调用

    sqlSessionFactoryBuilder.build(configuration)方法获取sqlSessionFactory的实例。

    由于整个加载过程没有过多的难点,所以就介绍到这里,感兴趣的朋友可以自己去源码,了解更多知识。

  • 相关阅读:
    微信公众号Markdown编辑器, 适合代码排版
    Java8-如何构建一个Stream
    Java8-Stream之数值流
    Java8学习(4)-Stream流
    Dubbo学习1-Hello world
    深入理解JVM垃圾收集机制(JDK1.8)
    持久层框架JPA与Mybatis该如何选型
    淇℃伅 [main] org.apache.catalina.startup.VersionLoggerListener.log Server.鏈嶅姟鍣
    Apache Tomcat下载、安装、配置图文教程
    IIS8.0 配置应用程序初始化功能
  • 原文地址:https://www.cnblogs.com/ljy-20180122/p/9374754.html
Copyright © 2020-2023  润新知