Spring声明式事务的实现方式

一、如何整合进Spring中的

默认大家对Spring都比较了解了,这里只说结果。都知道接口是不能被实例化的,那么接口是如何成为Bean的呢?

1.1 如何知道哪些是Mybatis的接口呢?

@MapperScan Spring中在配置类上加上这个注解。根据源码能看到还导入了 MapperScannerRegistrar

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(MapperScannerRegistrar.class)
@Repeatable(MapperScans.class)
public @interface MapperScan {}

public class MapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {}

MapperScannerRegistrar 会在配置类解析时候拿到 MapperScan 注解信息,并解析里面的参数。生成一个 MapperScannerConfigurer 信息。

从源码中能看到Mybatis的很多配置信息,都会被注入到 MapperScannerConfigurer 中。

public class MapperScannerConfigurer
    implements BeanDefinitionRegistryPostProcessor, InitializingBean, ApplicationContextAware, BeanNameAware {}

实现自BeanDefinitionRegistryPostProcessor会前置,拿到MapperScan中的basePackage,最终通过 ClassPathMapperScanner 扫描并添加到

BeanDefinitionRegistry 中。

到这里这种方式就能知道哪些是Mybatis中的Mapper接口了。

还有第二种方式当发现Spring容器中没有 MapperScannerConfigurer 。会自动注入一个

会直接指定哪些类被Mapper修饰,就将他生成Bean。


好了,到这里就知道如何来确定那些接口是要生成Mybatis接口的了。下面看下个问题。

1.2 Mapper接口是如何变成Spring Bean的?

接口是不能被实例化的,但是在Spring中如何想让接口实例化就可以使用FactoryBean + 动态代理的方式,实现接口类的实例化

MapperFactoryBean

二、Spring在哪里声明的SqlSession的实现逻辑?

通过Mybatis的学习知道SqlSession一共有2个包装类。SqlSessionManager和SqlSessionTemplate。那么SqlSession是在哪里指定用哪个的呢?

答案就在 MapperFactoryBean

public class MapperFactoryBean<T> extends SqlSessionDaoSupport implements FactoryBean<T> {
  private SqlSessionTemplate sqlSessionTemplate;
   
     public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
       if (this.sqlSessionTemplate == null || sqlSessionFactory != this.sqlSessionTemplate.getSqlSessionFactory()) {
         this.sqlSessionTemplate = createSqlSessionTemplate(sqlSessionFactory);
       }
     }
   
     @SuppressWarnings("WeakerAccess")
     protected SqlSessionTemplate createSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
       return new SqlSessionTemplate(sqlSessionFactory);
     }
}

三、Spring中声明式事务的实现方式是怎样的

看了Mybatis中事务这一章节,知道如果使用了SqlSessionTemplate,那么事务的权限就外包给了Spring。那么Spring中事务怎么处理的呢?

终于进入正题了。Spring中提供两种事务的能力。

声明式事务
编程式事务
3.1 声明式事务
使用 Transactional 修饰方法,其主要实现是使用切面实现。

TransactionAspectSupport#invokeWithinTransaction 。拦截方法。获取事务管理器。
这里我们先来思考下,通过前面的学习知道事务的最底层实现是jdbc驱动来实现的。

那么切面中要想实现,就必须保证切面中的线程执行的数据库操作,一定是同一个 SqlSession 这样才能在方法正常执行时候做commit,异常时候做rollback操作。

那我们看下他是如何保证切面中的数据库操作一定是同一个SqlSession的吧。这部分逻辑就在 SqlSessionTemplate 中。

获取当前线程是否已经有SqlSession了,如果有就直接使用,这样就保证在切面中的事务用的是同一个事务了。

3.2 编程式事务

TransactionTemplate#execute
编程是事务需要实现者自己来管理事务的,Spri

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值