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……

  • 相关阅读:
    uva11916 Emoogle Grid (BSGS)
    2016vijos 1-2 股神小L(堆)
    bzoj千题计划311:bzoj5017: [Snoi2017]炸弹(线段树优化tarjan构图)
    Oracle Profile 使用详解--zhuanzai
    通过srvctl add命令添加database信息到srvctl管理器-转
    Oracle Dataguard Standby Redo Log的两个实验
    MySQL数据的主从复制、半同步复制和主主复制详解-转
    解决oralce 11g dg搭建报错:ORA-16664、ORA-16714、ORA-16810问题--转
    oracle分布式事务总结-转载
    日志挖掘Logmnr
  • 原文地址:https://www.cnblogs.com/codeToSuccess/p/13906190.html
Copyright © 2011-2022 走看看