zoukankan      html  css  js  c++  java
  • SqlSessionTemplate使用SqlSessionFactoryBean实例化之谜(以及xml配置信息迁移到java的方法)

    最近在学习mybatis源码时,发现了一个问题。

    首先,在xml配置文件中配置了SqlSessionTemplate与SqlSessionFactoryBean。

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      <property name="dataSource" ref="dataSource" />
      <property name="configLocation" value="classpath:${mybatis.config}"/>
      <property name="mapperLocations" value="classpath*:mybatis/mapper.xml"/>
    </bean>
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
      <constructor-arg>
        <ref bean="sqlSessionFactory" />
      </constructor-arg>
    </bean>

    看起来,SqlSessionTemplate是使用SqlSessionFactoryBean实例化的。

    然而,查看SqlSessionTemplate的构造方法,发现:

    public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
      this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
    }

    SqlSessionTemplate其实是用SqlSessionFactory实例化的!

    可是xml中明明写着这个bean的类型是SqlSessionFactoryBean呀,难道SqlSessionFactoryBean继承或实现了SqlSessionFactory?

    继续查看源码,发现:

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

    总之,SqlSessionFactoryBean并没有继承或实现了SqlSessionFactory。

    这样就奇怪了,类型不匹配的话,SqlSessionTemplate到底是怎么实例化的?

    后来,通过百度发现:

    SqlSessionFactoryBean 实现了 Spring 的 FactoryBean 接口,
    就说明了由 Spring 最终创建的 bean 不是 SqlSessionFactoryBean 本身,
    而是工厂类的 getObject() 返回的方法的结果。
    这种情况下, Spring 将会在应用启动时为你创建 SqlSessionFactory 对象,然后将它以  SqlSessionFactory 为名来存储。

    好吧,这波操作666,本人完全没想到。

    本人猜测,可能是这样实现的(正好举一个xml迁移进java的例子):

    import org.apache.ibatis.session.SqlSessionFactory;
    import org.mybatis.spring.SqlSessionFactoryBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    import javax.annotation.Resource;
    import javax.sql.DataSource;
    
    @Configuration
    public class MybatisConfig {
        //从spring容器中获取配置数据源的其它bean对象
        @Resource
        private DataSource dataSource;
        //从spring容器中获取处理好的对象,对应:
        //classpath:${mybatis.config}
        @Resource
        private org.springframework.core.io.Resource configLocation;
        //从spring容器中获取处理好的对象,对应:
        //classpath*:mybatis/mapper.xml
        @Resource
        private org.springframework.core.io.Resource[] mapperLocations;
    
        @Bean(name="sqlSessionFactory")
        public SqlSessionFactory sqlSessionFactoryBeanTosqlSessionFactory() throws Exception {
            SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
            sqlSessionFactoryBean.setDataSource(dataSource);
            sqlSessionFactoryBean.setConfigLocation(configLocation);
            sqlSessionFactoryBean.setMapperLocations(mapperLocations);
            SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBean.getObject();
            //虽然new了SqlSessionFactoryBean,但是返回的是SqlSessionFactory
            return sqlSessionFactory;
        }
    }

    你以为xml中配了class,获得的对象就一定是class指定的对象吗?

    你以为是SqlSessionFactoryBean,其实是我SqlSessionFactory哒!

    不得不说,源码这波操作是真的6……

  • 相关阅读:
    matlab矩阵中如何去掉重复的行;如何找到相同的行,并找到其位置
    Coursera 机器学习 第9章(下) Recommender Systems 学习笔记
    机器学习基石笔记1——在何时可以使用机器学习(1)
    Coursera 机器学习 第9章(上) Anomaly Detection 学习笔记
    matlab安装过程的被要求的配置程序
    jdk环境变量配置
    Coursera 机器学习 第8章(下) Dimensionality Reduction 学习笔记
    Coursera 机器学习 第8章(上) Unsupervised Learning 学习笔记
    Coursera 机器学习 第7章 Support Vector Machines 学习笔记
    linux服务器---squid限制
  • 原文地址:https://www.cnblogs.com/codeToSuccess/p/13906190.html
Copyright © 2011-2022 走看看