spring整合mybatis源码解析

先看一下spring整合mybatis需要的配置Bean

@Configuration
@MapperScan(basePackages = {
   "com.bijian.mapper"})
@ComponentScan(basePackages = {
   "com.bijian"})
@Repository
public class MyBatisConfig {
       // =====>   spring.xml


	/**
	 * <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">  </bean>
	 *
	 * <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
	 *     datasource
	 *     mapper文件的路径
	 *     别名
	 *
	 *   </bean>
	 *
	 *   <mapper-scan basePackage=""/>
	 *   SqlSessionFactoryBean   创建的过程会初始化  sqlsession 数据源  事务  mapperProxyFactory
	 * @return
	 * @throws IOException
	 */
	@Bean    // =====  >    <bean  class="org.mybatis.spring.SqlSessionFactoryBean">
	public SqlSessionFactoryBean sqlSessionFactory( ) throws IOException {
   
		SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean();
		factoryBean.setDataSource(dataSource());
		// 设置 MyBatis 配置文件路径
		//factoryBean.setConfigLocation(new ClassPathResource("mybatis/mybatis-config.xml"));
		// 设置 SQL 映射文件路径
		//factoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/*.xml"));
		factoryBean.setTypeAliases(User.class);

		return factoryBean;


	}

    public DataSource dataSource() {
   
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUsername("root");
        dataSource.setPassword("123456");
        dataSource.setDriverClassName("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mydb1");
        return dataSource;
    }


}

大体介绍:
原理概述:

  1. 如何生成sqlSessionFactory对象不细说:就是以吧SqlSessionFactoryBean注入到容器中,它实现了FactoryBean,所以通过getObject方法来解析配置,生成包含所有mybatis所有信息的Configration对象,再构建一个完整的SqlSessionFactory对象;
  2. 如何通过mapper接口生成代理类注入容器中:扫描指定的mapper接口包,为每个接口生成一个BeanDefinition对象,再遍历这些BeanDefinition对象,修改其内容,把其class都设置成MapperFactoryBean,为其注入SqlSessionTamplate对象,因为其实现了BeanFactory对象,会调用其getObject方法返回mybatis生成的代理对象,这个代理对象的生成是mybatis自己做的,也就是为每个接口生成一个JDK动态代理,其动态代理对象中又有SqlSession对象,这样就可以执行了,就不细说了

我们先来解析SqlSessionFactoryBean对象所作的事,其实现了 FactoryBean,所以主要看起getObject方法所做的事,就是构建一个mybatis的SqlSessionFactory对象;

public SqlSessionFactory getObject() throws Exception {
   
    if (this.sqlSessionFactory == null) {
   
      afterPropertiesSet();
    }
    /**
     * 返回我们的sqlSessionFactory对象
     */
    return this.sqlSessionFactory;
  }
  public void afterPropertiesSet() throws Exception {
   
    notNull(dataSource, "Property 'dataSource' is required");
    notNull(sqlSessionFactoryBuilder, "Property 'sqlSessionFactoryBuilder' is required");
    state((configuration == null && configLocation == null) || !(configuration != null && configLocation != null),
        "Property 'configuration' and 'configLocation' can not specified with together");

    /**
     * 通过sqlSessionFactoryBuilder来构建我们的sqlSessionFactory
     */
    this.sqlSessionFactory = buildSqlSessionFactory();
  }

构建我们的sqlSessionFactory的实例

protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
   

    // 声明一个Configuration对象用于保存mybatis的所有的配置信息
    final Configuration targetConfiguration;

    XMLConfigBuilder xmlConfigBuilder = null;
    // 初始化 configuration 对象,和设置其 `configuration.variables` 属性
    /**
     * 判断当前的SqlSessionFactoryBean是否在配置@Bean的时候 factoryBean.setConfiguration();
     *
     */
    if (this.configuration != null) {
   
      /**
       * 把配置的SqlSessionFactoryBean配置的configuration 赋值给targetConfiguration
       */
      targetConfiguration = this.configuration;
      if (targetConfiguration.getVariables() == null) {
   
        targetConfiguration.setVariables(this.configurationProperties);
      } else if (this.configurationProperties != null) {
   
        targetConfiguration.getVariables().putAll(this.configurationProperties);
      }
    }
    /**
     * 对configLocation进行非空判断,由于我们配置了SqlSessionFactoryBean的configLocation属性设置
     *
     * @Bean public SqlSessionFactoryBean sqlSessionFactory( ) throws IOException { SqlSessionFactoryBean factoryBean
     *       =new SqlSessionFactoryBean(); factoryBean.setDataSource(dataSource()); factoryBean.setConfigLocation(new
     *       ClassPathResource("mybatis/mybatis-config.xml")); factoryBean.setMapperLocations(new
     *       PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/*.xml")); return factoryBean;
     *       }
     */

    else if (this.configLocation != null) {
   
      /**
       * 创建我们xml配置构建器对象,对mybatis/mybatis-config.xml配置文件进行解析 在这里以及把我们的mybaits-config.xml解析出要给document对象
       */
      xmlConfigBuilder = new XMLConfigBuilder(this.configLocation.getInputStream(), null, this.configurationProperties);
      /**
       * 因为我们在创建XMLConfigBuilder的时候已经把我们的Configuration对象创建出来了
       */
      targetConfiguration = xmlConfigBuilder.getConfiguration();
    } else {
   
      LOGGER.debug(
          () -> "Property 'configuration' or 'configLocation' not specified, using default MyBatis Configuration");
      targetConfiguration = new Configuration();
      /**
       * 判断configurationProperties不为空,那么就调用targetConfiguration.set方法 把configurationProperties注入到Configuration对象中
       */
      Optional.ofNullable(this.configurationProperties).ifPresent(targetConfiguration::setVariables);
    }

    /**
     * objectFactory不为空,那么就调用targetConfiguration.set方法 把objectFactory注入到Configuration对象中
     */
    Optional.ofNullable(this.objectFactory).ifPresent(targetConfiguration::setObjectFactory);
    /**
     * objectWrapperFactory不为空,那么就调用targetConfiguration.set方法把 ObjectWrapperFactory注入到Configuration对象中
     */
    Optional.ofNullable(this.objectWrapperFactory).ifPresent(targetConfiguration::setObjectWrapperFactory);

    /**
     * vfs不为空,那么就调用targetConfiguration.set方法把 vfs注入到Configuration对象中
     */
    Optional.ofNullable(this.vfs)<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值