Mybatis和Spring整合源码分析

本文深入剖析了Spring整合MyBatis的过程,包括SqlSessionFactoryBean的初始化、MapperScan的配置、MapperFactoryBean的工作原理及SqlSessionTemplate的实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  直接看到SqlSessionFactoryBean这个类,实现了FactoryBean和InitializingBean接口

  FactoryBean接口:

public SqlSessionFactory getObject() throws Exception {
    if (this.sqlSessionFactory == null) {
      afterPropertiesSet();
    }
	
	//返回SqlSessionFactory的实例
    return this.sqlSessionFactory;
}
public Class<? extends SqlSessionFactory> getObjectType() {
     //返回类型为SqlSessionFactory类型
    return this.sqlSessionFactory == null ? SqlSessionFactory.class : this.sqlSessionFactory.getClass();
}
//单例
public boolean isSingleton() {
    return true;
}

  InitializingBean接口:

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");
	
	//看这里,实例话sqlSessionFactory对象
    this.sqlSessionFactory = buildSqlSessionFactory();
}
protected SqlSessionFactory buildSqlSessionFactory() throws Exception {
	
    //省略部分源码 (一堆属性的封装, 之前文章mybatis,xml配置文件解析时候,分析过了部分属性了)	
	
	//一般指定该属性mapperLocations ,配置mapper xml文件的路径
    if (this.mapperLocations != null) {
      if (this.mapperLocations.length == 0) {
        LOGGER.warn(() -> "Property 'mapperLocations' was specified but matching resources are not found.");
      } else {
        for (Resource mapperLocation : this.mapperLocations) {
          if (mapperLocation == null) {
            continue;
          }
          try {
           //解析mapper xml文件
           //主要为
           //解析的resultMap标签的内容会加入configuration的resultMaps(Map)中,key为namespace加resultMap标签的id属性
           //解析的sql内容最终包装为MappedStatement,加入到configuration的mappedStatements(map)中,key为namespace加自己标签的id属性
          //将mapper的接口类型和生成的代理工厂类(MapperProxyFactory)注册到Configuration的mapperRegistry的knownMappers属性中
            XMLMapperBuilder xmlMapperBuilder = new XMLMapperBuilder(mapperLocation.getInputStream(),
                targetConfiguration, mapperLocation.toString(), targetConfiguration.getSqlFragments());
            xmlMapperBuilder.parse();
          } catch (Exception e) {
            throw new NestedIOException("Failed to parse mapping resource: '" + mapperLocation + "'", e);
          } finally {
            ErrorContext.instance().reset();
          }
          LOGGER.debug(() -> "Parsed mapper file: '" + mapperLocation + "'");
        }
      }
    } else {
      LOGGER.debug(() -> "Property 'mapperLocations' was not specified.");
    }
	
	//返回DefaultSqlSessionFactory实例
    return this.sqlSessionFactoryBuilder.build(targetConfiguration);
  }

  再来看到MapperScan注解。Import了MapperScannerRegistrar类,实现了ImportBeanDefinitionRegistrar接口

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
@Repeatable(MapperScans.class)
public @interface MapperScan {
    //省略属性

  看到MapperScannerRegistrar类的registerBeanDefinitions方法

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    //获取MapperScan注解值
    AnnotationAttributes mapperScanAttrs = AnnotationAttributes
        .fromMap(importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName()));
    if (mapperScanAttrs != null) {
      registerBeanDefinitions(importingClassMetadata, mapperScanAttrs, registry,
          generateBaseBeanName(importingClassMetadata, 0));
} 
void registerBeanDefinitions(AnnotationMetadata annoMeta, AnnotationAttributes annoAttrs,
      BeanDefinitionRegistry registry, String beanName) {
	
	//实例化一个BeanDefinitionBuilder,beanClass为MapperScannerConfigurer
    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MapperScannerConfigurer.class);
    builder.addPropertyValue("processPropertyPlaceHolders", true);
	
	//配置扫描的注解类型
    Class<? extends Annotation> annotationClass = annoAttrs.getClass("annotationClass");
    if (!Annotation.class.equals(annotationClass)) {
      builder.addPropertyValue("annotationClass", annotationClass);
    }
	//配置扫描的接口类型	
    Class<?> markerInterface = annoAttrs.getClass("markerInterface");
    if (!Class.class.equals(markerInterface)) {
      builder.addPropertyValue("markerInterface", markerInterface);
    }
	
	//可以自定义spring组件的name
    Class<? extends BeanNameGenerator> generatorClass = annoAttrs.getClass("nameGenerator");
    if (!BeanNameGenerator.class.equals(generatorClass)) {
      builder.addPropertyValue("nameGenerator", BeanUtils.instantiateClass(generatorClass));
    }
	
	//返回的接口的代理类型,默认为MapperFactoryBean,一般这个就够了
    Class<? extends MapperFactoryBean> mapperFactoryBeanClass = annoAttrs.getClass("factoryBean");
    if (!MapperFactoryBean.class.equals(mapperFactoryBeanClass)) {
      builder.addPropertyValue("mapperFactoryBeanClass", mapperFactoryBeanClass);
    }
	
	//配置指定的sqlSessionTemplate,spring容器中只有一个的话,不需要配置
    String sqlSessionTemplateRef = annoAttrs.getString("sqlSessionTemplateRef");
    if (StringUtils.hasText(sqlSessionTemplateRef)) {
      builder.addPropertyValue("sqlSessionTemplateBeanName", annoAttrs.getString("sqlSessionTemplateRef"));
    }

    //配置指定的sqlSessionFactory,spring容器中只有一个的话,不需要配置
    String sqlSessionFactoryRef = annoAttrs.getString("sqlSessionFactoryRef");
    if (StringUtils.hasText(sqlSessionFactoryRef)) {
      builder.addPropertyValue("sqlSessionFactoryBeanName", annoAttrs.getString("sqlSessionFactoryRef"));
    }
		
    List<String> basePackages = new ArrayList<>();
    
    //添加要扫描的路径
    basePackages.addAll(
        Arrays.stream(annoAttrs.getStringArray("value")).filter(StringUtils::hasText).collect(Collectors.toList()));

    basePackages.addAll(Arrays.stream(annoAttrs.getStringArray("basePackages")).filter(StringUtils::hasText)
        .collect(Collectors.toList()));

    basePackages.addAll(Arrays.stream(annoAttrs.getClassArray("basePackageClasses")).map(ClassUtils::getPackageName)
        .collect(Collectors.toList()));
        
    if (basePackages.isEmpty()) {
      basePackages.add(getDefaultBasePackage(annoMeta));
    }
	
	//是否懒加载
    String lazyInitialization = annoAttrs.getString("lazyInitialization");
    if (StringUtils.hasText(lazyInitialization)) {
      builder.addPropertyValue("lazyInitialization", lazyInitialization);
    }
	
	//指定扫描到的生成的bean的scope,默认单例
	String defaultScope = annoAttrs.getString("defaultScope");
    if (!AbstractBeanDefinition.SCOPE_DEFAULT.equals(defaultScope)) {
      builder.addPropertyValue("defaultScope", defaultScope);
    }

    builder.addPropertyValue("basePackage", StringUtils.collectionToCommaDelimitedString(basePackages));
	
	//注册MapperScannerConfigurer到容器中
    registry.registerBeanDefinition(beanName, builder.getBeanDefinition());

  }

  看到MapperScannerConfigurer类,实现了BeanDefinitionRegistryPostProcessor接口,看到postProcessBeanDefinitionRegistry方法

public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    //占位符的解析
    if (this.processPropertyPlaceHolders) {
      processPropertyPlaceHolders();
    }
	
	//实例化scanner进行扫描
    ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);
    scanner.setAddToConfig(this.addToConfig);
    scanner.setAnnotationClass(this.annotationClass);
    scanner.setMarkerInterface(this.markerInterface);
    scanner.setSqlSessionFactory(this.sqlSessionFactory);
    scanner.setSqlSessionTemplate(this.sqlSessionTemplate);
    scanner.setSqlSessionFactoryBeanName(this.sqlSessionFactoryBeanName);
    scanner.setSqlSessionTemplateBeanName(this.sqlSessionTemplateBeanName);
    scanner.setResourceLoader(this.applicationContext);
    scanner.setBeanNameGenerator(this.nameGenerator);
    scanner.setMapperFactoryBeanClass(this.mapperFactoryBeanClass);
    if (StringUtils.hasText(lazyInitialization)) {
      scanner.setLazyInitialization(Boolean.valueOf(lazyInitialization));
    }
    if (StringUtils.hasText(defaultScope)) {
      scanner.setDefaultScope(defaultScope);
    }
    //注册扫描的过滤器
    scanner.registerFilters();
    //扫描了
    scanner.scan(
        StringUtils.tokenizeToStringArray(this.basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS));
}
public void registerFilters() {
    boolean acceptAllInterfaces = true;
	
    // if specified, use the given annotation and / or marker interface
    //如果配置了annotationClas 属性,给includeFilters容器中添加该属性
    if (this.annotationClass != null) {
      addIncludeFilter(new AnnotationTypeFilter(this.annotationClass));
      acceptAllInterfaces = false;
    }
		
    // override AssignableTypeFilter to ignore matches on the actual marker interface	
    //配置了markerInterface属性
    if (this.markerInterface != null) {
      addIncludeFilter(new AssignableTypeFilter(this.markerInterface) {
      	//忽略掉自己
        @Override
        protected boolean matchClassName(String className) {
          return false;
        }
      });
      acceptAllInterfaces = false;
    }
	
	//没有配置annotationClas 和markerInterface  , 则全都可以匹配,固定返回true
    if (acceptAllInterfaces) {
      // default include filter that accepts all classes
      addIncludeFilter((metadataReader, metadataReaderFactory) -> true);
    }
	
	//排除package-info.java
    // exclude package-info.java
    addExcludeFilter((metadataReader, metadataReaderFactory) -> {
      String className = metadataReader.getClassMetadata().getClassName();
      return className.endsWith("package-info");
    });
}
public Set<BeanDefinitionHolder> doScan(String... basePackages) {
    //扫描包,并生成beanDefinitions返回,扫描的具体逻辑之前讲spring标签解析的时候以及分析过了,这里就不再细说了
    Set<BeanDefinitionHolder> beanDefinitions = super.doScan(basePackages);
	
    if (beanDefinitions.isEmpty()) {
      LOGGER.warn(() -> "No MyBatis mapper was found in '" + Arrays.toString(basePackages)
          + "' package. Please check your configuration.");
    } else {
      //看这里
      processBeanDefinitions(beanDefinitions);
    }

    return beanDefinitions;
}
private void processBeanDefinitions(Set<BeanDefinitionHolder> beanDefinitions) {
    AbstractBeanDefinition definition;
    BeanDefinitionRegistry registry = getRegistry();
    //循环处理所有的beanDefinition
    for (BeanDefinitionHolder holder : beanDefinitions) {
      definition = (AbstractBeanDefinition) holder.getBeanDefinition();
      boolean scopedProxy = false;
      if (ScopedProxyFactoryBean.class.getName().equals(definition.getBeanClassName())) {
        definition = (AbstractBeanDefinition) Optional
            .ofNullable(((RootBeanDefinition) definition).getDecoratedDefinition())
            .map(BeanDefinitionHolder::getBeanDefinition).orElseThrow(() -> new IllegalStateException(
                "The target bean definition of scoped proxy bean not found. Root bean definition[" + holder + "]"));
        scopedProxy = true;
      }
      //获取到mapper的接口类型
      String beanClassName = definition.getBeanClassName();
      LOGGER.debug(() -> "Creating MapperFactoryBean with name '" + holder.getBeanName() + "' and '" + beanClassName
          + "' mapperInterface");

      // the mapper interface is the original class of the bean
      // but, the actual class of the bean is MapperFactoryBean
      //给构造函数的参数添加了mapper的接口类型的参数!!!
      definition.getConstructorArgumentValues().addGenericArgumentValue(beanClassName); // issue #59
      //将BeanClass替换为MapperFactoryBean.class!!!
      definition.setBeanClass(this.mapperFactoryBeanClass);

      definition.getPropertyValues().add("addToConfig", this.addToConfig);

      // Attribute for MockitoPostProcessor
      // https://github.com/mybatis/spring-boot-starter/issues/475
      definition.setAttribute(FACTORY_BEAN_OBJECT_TYPE, beanClassName);
		
	  //是否配置了sqlSessionFactory或者sqlSessionTemplate,容器中只有一个的情况下,可以不配置
      boolean explicitFactoryUsed = false;
      if (StringUtils.hasText(this.sqlSessionFactoryBeanName)) {
        definition.getPropertyValues().add("sqlSessionFactory",
            new RuntimeBeanReference(this.sqlSessionFactoryBeanName));
        explicitFactoryUsed = true;
      } else if (this.sqlSessionFactory != null) {
        definition.getPropertyValues().add("sqlSessionFactory", this.sqlSessionFactory);
        explicitFactoryUsed = true;
      }

      if (StringUtils.hasText(this.sqlSessionTemplateBeanName)) {
        if (explicitFactoryUsed) {
          LOGGER.warn(
              () -> "Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
        }
        definition.getPropertyValues().add("sqlSessionTemplate",
            new RuntimeBeanReference(this.sqlSessionTemplateBeanName));
        explicitFactoryUsed = true;
      } else if (this.sqlSessionTemplate != null) {
        if (explicitFactoryUsed) {
          LOGGER.warn(
              () -> "Cannot use both: sqlSessionTemplate and sqlSessionFactory together. sqlSessionFactory is ignored.");
        }
        definition.getPropertyValues().add("sqlSessionTemplate", this.sqlSessionTemplate);
        explicitFactoryUsed = true;
      }
	
	  //没有配置,没有关系
      if (!explicitFactoryUsed) {
        LOGGER.debug(() -> "Enabling autowire by type for MapperFactoryBean with name '" + holder.getBeanName() + "'.");
         // 设置AutowireMod为AUTOWIRE_BY_TYPE,(MapperFactoryBean的父类有SqlSessionFactory属性的set方法,该方法会对SqlSessionTemplate属性赋值)
        definition.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_BY_TYPE);
      }
	  
      definition.setLazyInit(lazyInitialization);

      if (scopedProxy) {
        continue;
      }
		
      if (ConfigurableBeanFactory.SCOPE_SINGLETON.equals(definition.getScope()) && defaultScope != null) {
        definition.setScope(defaultScope);
      }
      
      //如果不是单列,重新注册新的beanDefinition替换原来的单列beanDefinition
      
      if (!definition.isSingleton()) {
        //这个createScopedProxy方法之前讲spring的时候没讲,刚好现在提一下。
        //该方法会将原本的bean的beanName拼上scopedTarget.前缀,设置autowireCandidate属性为false(不使用该bean进行依赖注入),注册为一个新的beanDefinition
        //该方法注返回的的是ScopedProxyFactoryBean类型的BeanDefinition,使用了原本的beanName
        //实现了FactoryBean接口,返回的对象为ProxyFactory类型,给ProxyFactory增加了advice
        //ProxyFactory的TargetSource(走到aop拦截方法每次都会调用getTarget)为SimpleBeanTargetSource,重写了TargetSource的getTarget方法( getBeanFactory().getBean(getTargetBeanName() (这里是加了scopedTarget.前缀的) ))
        BeanDefinitionHolder proxyHolder = ScopedProxyUtils.createScopedProxy(holder, registry, true);
        if (registry.containsBeanDefinition(proxyHolder.getBeanName())) {
          //如果有同名的,移除原本的bedefinition
          registry.removeBeanDefinition(proxyHolder.getBeanName());
        }
        //注册新的bedefinition
        registry.registerBeanDefinition(proxyHolder.getBeanName(), proxyHolder.getBeanDefinition());
      }
    }
}

  接下来看到MapperFactoryBean,实现了FactoryBean接口

//这里的mapperInterface为原本mapper的接口类型
public MapperFactoryBean(Class<T> mapperInterface) {
    this.mapperInterface = mapperInterface;
}
//看这里,获取到mybatis的MapperProxyFactory , 着重看到getSqlSession方法
public T getObject() throws Exception {
    return getSqlSession().getMapper(this.mapperInterface);
}
//原本mapper的接口类型
public Class<T> getObjectType() {
    return this.mapperInterface;
}
//单例
public boolean isSingleton() {
    return true;
}

  看到父类SqlSessionDaoSupport

//从父类获取到sqlSessionTemplate
public SqlSession getSqlSession() {
    return this.sqlSessionTemplate;
}
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
    if (this.sqlSessionTemplate == null || sqlSessionFactory != this.sqlSessionTemplate.getSqlSessionFactory()) {
      //实例化SqlSessionTemplate对象。持有了sqlSessionFactory。
      this.sqlSessionTemplate = createSqlSessionTemplate(sqlSessionFactory);
    }
}

  看到父类SqlSessionTemplate,实现了sqlSession接口,增删改查的方法全部重写为用sqlSessionProxy 调用。

public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
      PersistenceExceptionTranslator exceptionTranslator) {

    notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
    notNull(executorType, "Property 'executorType' is required");
	
	//持有了sqlSessionFactory
    this.sqlSessionFactory = sqlSessionFactory;
    this.executorType = executorType;
    this.exceptionTranslator = exceptionTranslator;
    //看SqlSessionInterceptor的invoke方法
    this.sqlSessionProxy = (SqlSession) newProxyInstance(SqlSessionFactory.class.getClassLoader(),
        new Class[] { SqlSession.class }, new SqlSessionInterceptor());
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      //获取sqlSession
      SqlSession sqlSession = getSqlSession(SqlSessionTemplate.this.sqlSessionFactory,
          SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
      try {
        //使用获取到的sqlSession对象反射调用方法。
        Object result = method.invoke(sqlSession, args);
        if (!isSqlSessionTransactional(sqlSession, SqlSessionTemplate.this.sqlSessionFactory)) {
          // force commit even on non-dirty sessions because some databases require
          // a commit/rollback before calling close()
          sqlSession.commit(true);
        }
        return result;
      } catch (Throwable t) {
        Throwable unwrapped = unwrapThrowable(t);
        if (SqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
          // release the connection to avoid a deadlock if the translator is no loaded. See issue #22
          closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
          sqlSession = null;
          Throwable translated = SqlSessionTemplate.this.exceptionTranslator
              .translateExceptionIfPossible((PersistenceException) unwrapped);
          if (translated != null) {
            unwrapped = translated;
          }
        }
        throw unwrapped;
      } finally {
        if (sqlSession != null) {
          closeSqlSession(sqlSession, SqlSessionTemplate.this.sqlSessionFactory);
        }
      }
}
public static SqlSession getSqlSession(SqlSessionFactory sessionFactory, ExecutorType executorType,
      PersistenceExceptionTranslator exceptionTranslator) {

    notNull(sessionFactory, NO_SQL_SESSION_FACTORY_SPECIFIED);
    notNull(executorType, NO_EXECUTOR_TYPE_SPECIFIED);
	
	//使用sessionFactory从threadlocal获取SqlSessionHolder对象,TransactionSynchronizationManager这玩意在spring事务的时候详细讲过了
	//第一次进来肯定没有的
    SqlSessionHolder holder = (SqlSessionHolder) TransactionSynchronizationManager.getResource(sessionFactory);

    SqlSession session = sessionHolder(executorType, holder);
    if (session != null) {
      return session;
    }

    LOGGER.debug(() -> "Creating a new SqlSession");
    //openSession获取一个新的SqlSession
    session = sessionFactory.openSession(executorType);
	
	//看这里
    registerSessionHolder(sessionFactory, executorType, exceptionTranslator, session);

    return session;
}
private static void registerSessionHolder(SqlSessionFactory sessionFactory, ExecutorType executorType,
      PersistenceExceptionTranslator exceptionTranslator, SqlSession session) {
    SqlSessionHolder holder;
    //判断synchronizations是否初始化
    //TransactionSynchronizationManager的initSynchronization会初始化synchronizations
    //spring事务开启和恢复的代码会调用initSynchronization
    //也就是说没有事务的情况下TransactionSynchronizationManager.bindResource不会调用(除非你手动调用),每次都是不同的sqlSession去调用增删改查
    if (TransactionSynchronizationManager.isSynchronizationActive()) {
      Environment environment = sessionFactory.getConfiguration().getEnvironment();

      if (environment.getTransactionFactory() instanceof SpringManagedTransactionFactory) {
        LOGGER.debug(() -> "Registering transaction synchronization for SqlSession [" + session + "]");
		
        holder = new SqlSessionHolder(session, executorType, exceptionTranslator);
        //向threadlocal放入sqlSessionFactory为key,SqlSessionHolder为value的map
        TransactionSynchronizationManager.bindResource(sessionFactory, holder);
        TransactionSynchronizationManager
            .registerSynchronization(new SqlSessionSynchronization(holder, sessionFactory));
        holder.setSynchronizedWithTransaction(true);
        holder.requested();
      } else {
        if (TransactionSynchronizationManager.getResource(environment.getDataSource()) == null) {
          LOGGER.debug(() -> "SqlSession [" + session
              + "] was not registered for synchronization because DataSource is not transactional");
        } else {
          throw new TransientDataAccessResourceException(
              "SqlSessionFactory must be using a SpringManagedTransactionFactory in order to use Spring transaction synchronization");
        }
      }
    } else {
      LOGGER.debug(() -> "SqlSession [" + session
          + "] was not registered for synchronization because synchronization is not active");
    }

}

  最后看到BaseExecutor的getConnection方法,和Spring整合则使用的是Spring的事务管理器SpringManagedTransaction

protected Connection getConnection(Log statementLog) throws SQLException {
    //从事务管理器获取连接对象
    Connection connection = transaction.getConnection();
    if (statementLog.isDebugEnabled()) {
      return ConnectionLogger.newInstance(connection, statementLog, queryStack);
    } else {
      return connection;
    }
}

  SpringManagedTransaction的getConnection方法

public Connection getConnection() throws SQLException {
    if (this.connection == null) {
      //获取连接对象
      openConnection();
    }
    return this.connection;
}
private void openConnection() throws SQLException {
    //看这里
    this.connection = DataSourceUtils.getConnection(this.dataSource);
    this.autoCommit = this.connection.getAutoCommit();
    this.isConnectionTransactional = DataSourceUtils.isConnectionTransactional(this.connection, this.dataSource);

    LOGGER.debug(() -> "JDBC Connection [" + this.connection + "] will"
        + (this.isConnectionTransactional ? " " : " not ") + "be managed by Spring");
}
public static Connection getConnection(DataSource dataSource) throws CannotGetJdbcConnectionException {
		try {
			//接着看
			return doGetConnection(dataSource);
		}
		catch (SQLException ex) {
			throw new CannotGetJdbcConnectionException("Failed to obtain JDBC Connection", ex);
		}
		catch (IllegalStateException ex) {
			throw new CannotGetJdbcConnectionException("Failed to obtain JDBC Connection: " + ex.getMessage());
		}
}
public static Connection doGetConnection(DataSource dataSource) throws SQLException {
		Assert.notNull(dataSource, "No DataSource specified");
		
		//这里就很熟悉了之前讲事务的时候详细讲过了
		//这里的连接对象是在事务开启的时候设置进去的
		//这样myabtis使用的连接对象和spring当前事务的持有的连接对象就是一个对象了,spring控制的该连接对象的提交回滚
		ConnectionHolder conHolder = (ConnectionHolder) TransactionSynchronizationManager.getResource(dataSource);
		if (conHolder != null && (conHolder.hasConnection() || conHolder.isSynchronizedWithTransaction())) {
			conHolder.requested();
			if (!conHolder.hasConnection()) {
				logger.debug("Fetching resumed JDBC Connection from DataSource");
				conHolder.setConnection(fetchConnection(dataSource));
			}
			//返回连接对象
			return conHolder.getConnection();
		}
		// Else we either got no holder or an empty thread-bound holder here.
		
		logger.debug("Fetching JDBC Connection from DataSource");
		//直接使用dataSource.getConnection()获取连接对象返回
		Connection con = fetchConnection(dataSource);
		
		//判断synchronizations是否初始化
		if (TransactionSynchronizationManager.isSynchronizationActive()) {
			try {
				// Use same Connection for further JDBC actions within the transaction.
				// Thread-bound object will get removed by synchronization at transaction completion.
				ConnectionHolder holderToUse = conHolder;
				if (holderToUse == null) {
					holderToUse = new ConnectionHolder(con);
				}
				else {
					holderToUse.setConnection(con);
				}
				holderToUse.requested();
				TransactionSynchronizationManager.registerSynchronization(
						new ConnectionSynchronization(holderToUse, dataSource));
				holderToUse.setSynchronizedWithTransaction(true);
				if (holderToUse != conHolder) {
				    //绑定数据源和连接对象的映射到threadlocal中
					TransactionSynchronizationManager.bindResource(dataSource, holderToUse);
				}
			}
			catch (RuntimeException ex) {
				// Unexpected exception from external delegation call -> close Connection and rethrow.
				releaseConnection(con, dataSource);
				throw ex;
			}
		}

		return con;
	}

  到此Spring整合mybatis的源码就分析结束了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值