互联网架构-Spring5.0源码深度解析-025:SpringBean声明事务底层实现原理

1 Spring声明事务底层源码分析预览

课程内容:
1、回顾SpringAop底层调用链关系
2、构建Spring整合JDBC环境模式事务操作
3、@Transactional事务注解底层源码
4、@EnableTransactionManagement源码分析

1.事务保证数据一致性 一般在Service层方法上加上@Transactional(调用Dao层)
2.环绕通知+手动事务可以实现声明事务

2 SpringAop切面编程底层原理回顾

SpringAop中所有的通知最终是如何执行的?
调用链关系,采用递归+责任链设计模式实现。
AbstractAutoProxyCreator 使用该类创建目标对象代理类
MethodInterceptor子类下有很多自定义通知(前置、后置、环绕、异常等),还有一个子类TransactionInterceptor 事务拦截
在这里插入图片描述
SpringAop底层原理分析

  1. 首先启动SpringAop时,会使用@EnableAspectJAutoProxy注解
  2. 将@Import(AspectJAutoProxyRegistrar.class)注入SpringIOC容器中
  3. AspectJAutoProxyRegistrar中会注册对象
    BeanId:org.springframework.aop.config.internalAutoProxyCreator
    BeanClass :AnnotationAwareAspectJAutoProxyCreator
  4. AnnotationAwareAspectJAutoProxyCreator最为核心:使用后置通知在bean的对象初始化的时候,实现对代理对象的增强。
    AnnotationAwareAspectJAutoProxyCreator祖宗:AbstractAutoProxyCreator 祖宗:BeanPostProcessor
  5. 被代理对象在初始化的时候,AbstractAutoProxyCreator 经过这样的一个类拦截。判断该被代理对象是否有被有实现过接口,如果有实现过接口就使用jdk动态代理,如果没有实现接口则使用cglib动态代理。
  6. 当我们调用目标方法的时候,会执行JdkDynamicAopProxy的invoke方法,再使用递归算法循环遍历执行MethodInterceptor(每个通知)的invoke方法。

3 基于Spring注解方式构建整合JDBC环境01

Maven依赖

<dependencies>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.5.RELEASE</version>
    </dependency>
    <!-- mysql 依赖 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jdbc</artifactId>
        <version>5.0.5.RELEASE</version>
    </dependency>
</dependencies>

配置类

@Configuration
@ComponentScan("com.mayikt")
public class MyConfig {

    // 注入到IOC容器中 beanid=dataSource,class=DataSource类的完整路径地址
    // 配置数据源
    @Bean
    public DataSource dataSource(){
        MysqlDataSource mysqlDataSource = new MysqlDataSource();
        mysqlDataSource.setUser("root");
        mysqlDataSource.setPassword("root");
        mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&useSSL=false");
        mysqlDataSource.setDatabaseName("test");
        return mysqlDataSource;
    }

    // 注入jdbcTemplate
    @Bean
    public JdbcTemplate jdbcTemplate(){
        return new JdbcTemplate(dataSource());
    }
}

Service层

public interface OrderService {
    public void addOrder();
}
@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private OrderDao orderDao;

    @Override
    @Transactional
    public void addOrder() {
        orderDao.addOrder();
        int i = 1 / 0;
    }
}

Dao层

@Repository
public class OrderDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public void addOrder() {
        jdbcTemplate.update("insert into order_info values(null,'mayikt','zhangsan','1111')");
    }
}

测试类

public class JdbcTest {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(MyConfig.class);
        OrderService orderService = annotationConfigApplicationContext.getBean("orderServiceImpl", OrderService.class);
        orderService.addOrder();
    }
} 

4 基于Spring注解方式构建整合JDBC环境04

关闭事务运行结果:
在这里插入图片描述
开启事务运行结果:
在这里插入图片描述
使用事务之后,为什么有把Aop开启呢?
事务本身就是基于AOP实现的。

5 Spring声明事务底层源码分析01

Spring事务底层源码分析

  1. @EnableTransactionManagement 开启事务
  2. @Import(TransactionManagementConfigurationSelector.class)
  3. 默认使用PROXY:选择器new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()}
  4. AutoProxyRegistrar会将InfrastructureAdvisorAutoProxyCreator注册到ioc容器中
    Beanid: internalAutoProxyCreator
    Value: InfrastructureAdvisorAutoProxyCreator
  5. ProxyTransactionManagementConfiguration 将tansactionInterceptor对象注册到ioc容器
    Beanid: TransactionInterceptor
    Value: tansactionInterceptor
    在这里插入图片描述

6 Spring声明事务底层源码分析02

重点分析:InfrastructureAdvisorAutoProxyCreator、tansactionInterceptor
在这里插入图片描述
6. 由类关系图可知,InfrastructureAdvisorAutoProxyCreator类祖宗是后置处理器,Bean对象在初始化之后都会判断是否需要创建代理类(根据是否有加上@Transactional)
在这里插入图片描述
7. 当调用目标方法的时候,进入代理类的invoke方法,执行到TransactionInterceptor中的invoke方法,里面封装手动事务相关处理逻辑。在这里插入图片描述

7 Spring声明事务失效之谜原因

在这里插入图片描述
Spring的事务为什么会失效?
如果service 没有将异常抛出的时候,事务可能会失效,底层invokeWithinTransaction方法中没有捕获到异常进行回滚事务操作。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值