spring源码系列9:事务代理的创建(上)

简介: spring源码系列9:事务代理的创建(上)

回顾下AOP相关知识点:


  1. 静态代理与JDK动态代理与CGLIB动态代理
  2. Spring中的InstantiationAwareBeanPostProcessor和BeanPostProcessor的区别
  3. spring源码系列8:AOP源码解析之代理的创建

我们总结出AOP公式

  • JDK动态代理(Proxy+InvocationHandler)+advised
  • CGLB动态代理(Enhancer+MethodInterceptor)+advised

本质都是在内存中生成了新的字节码类。

这节我们看看事务是如何利用AOP实现的。


事务代理生成过程


一、@EnableTransactionManagement配置事务环境

@EnableTransactionManagement的@Import(TransactionManagementConfigurationSelector.class)引入TransactionManagementConfigurationSelector.class。此类

@Override
  protected String[] selectImports(AdviceMode adviceMode) {
    switch (adviceMode) {
      case PROXY:
        return new String[] {AutoProxyRegistrar.class.getName(),
            ProxyTransactionManagementConfiguration.class.getName()};
      case ASPECTJ:
        return new String[] {
            TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
      default:
        return null;
    }
  }

PROXY:情况下,会注册两个类:


>AutoProxyRegistrar:

实现了ImportBeanDefinitionRegistrar。其接口方法registerBeanDefinitions会向仓库注册Bean定义

InfrastructureAdvisorAutoProxyCreatorInfrastructureAdvisorAutoProxyCreator继承了AbstractAdvisorAutoProxyCreator间接继承了AbstractAutoProxyCreator

在AOP代理生成那一节,我们讲过。AnnotationAwareAspectJAutoProxyCreator也是间接继承了AbstractAutoProxyCreator

在AOP实现原理中AbstractAutoProxyCreator做了大部分工作。

从这一点看,事务代理对象创建过程,与AOP代理对象过程是一样的,关键就在这个AbstractAutoProxyCreator类


>ProxyTransactionManagementConfiguration

是一个@Configuration。有三个@Bean注解方法。

  • transactionAdvisor()
  • transactionAttributeSource()
  • transactionInterceptor()
@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
  @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
    BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
    advisor.setTransactionAttributeSource(transactionAttributeSource());
    advisor.setAdvice(transactionInterceptor());
    advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
    return advisor;
  }
  @Bean
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public TransactionAttributeSource transactionAttributeSource() {
    return new AnnotationTransactionAttributeSource();
  }
  @Bean
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public TransactionInterceptor transactionInterceptor() {
    TransactionInterceptor interceptor = new TransactionInterceptor();
    interceptor.setTransactionAttributeSource(transactionAttributeSource());
    if (this.txManager != null) {
      interceptor.setTransactionManager(this.txManager);
    }
    return interceptor;
  }
}


1.BeanFactoryTransactionAttributeSourceAdvisor

首先:transactionAdvisor()方法会向仓库中注册一个BeanFactoryTransactionAttributeSourceAdvisor。


image.png


从其继承关系上看,他是一个Advisor,并且还是PointcutAdvisor.关于Advisor,上节我们分析过他是封装了(Advice+Pointcut)

既然都有了Advisor了,那Advice和Pointcut在哪里呢?

BeanFactoryTransactionAttributeSourceAdvisor有一个pointcut 属性,会new 一个TransactionAttributeSourcePointcut。

private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
    @Override
    protected TransactionAttributeSource getTransactionAttributeSource() {
      return transactionAttributeSource;
    }
  };


image.png


从其继承关系,我们可以看出他其实就是一个Pointcut。

至此,就剩下Advice没有被发现。


2.TransactionAttributeSource: 其次:transactionAttributeSource()会向仓库中注册一个AnnotationTransactionAttributeSource。这个AnnotationTransactionAttributeSource干嘛用的呢?

BeanFactoryTransactionAttributeSourceAdvisor.setTransactionAttributeSource(transactionAttributeSource())
属性值
private TransactionAttributeSource transactionAttributeSource;
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
    @Override
    protected TransactionAttributeSource getTransactionAttributeSource() {
      return transactionAttributeSource;
    }
  };
TransactionAttributeSourcePointcut的matche方法
@Override
  public boolean matches(Method method, Class<?> targetClass) {
    if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
      return false;
    }
    TransactionAttributeSource tas = getTransactionAttributeSource();
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
  }


AnnotationTransactionAttributeSource对象会赋值给BeanFactoryTransactionAttributeSourceAdvisor的transactionAttributeSource属性。pointcut属性初始化时,new 一个TransactionAttributeSourcePointcut类并实现getTransactionAttributeSource()方法,getTransactionAttributeSource()方法正好返回了transactionAttributeSource属性。


也就是说TransactionAttributeSourcePointcut的getTransactionAttributeSource()方法返回的是AnnotationTransactionAttributeSource

3.TransactionInterceptor : 最后:transactionInterceptor()方法,会向仓库中注册一个TransactionInterceptor类。


image.png


TransactionInterceptor从继承关系看他是一个Advice. 也就是增强器,是对事务真正处理地方。

有了Advice+Pointcut。Advice+Pointcut = Advisor 。 Advisor+TargetSource = Advised

有了Advised ,这样spring事务不正是套用了AOP的基础吗。


相关文章
|
24天前
|
SQL Java 关系型数据库
Spring事务传播机制:7种姿势教你玩转"事务接力赛"
事务传播机制是Spring框架中用于管理事务行为的重要概念,它决定了在方法调用时事务如何传递与执行。通过7种传播行为,开发者可以灵活控制事务边界,适应不同业务场景。例如:REQUIRED默认加入或新建事务,REQUIRES_NEW独立开启新事务,NESTED支持嵌套回滚等。合理使用传播机制不仅能保障数据一致性,还能提升系统性能与健壮性。掌握这“七种人格”,才能在复杂业务中游刃有余。
|
2月前
|
Java 关系型数据库 数据库
深度剖析【Spring】事务:万字详解,彻底掌握传播机制与事务原理
在Java开发中,Spring框架通过事务管理机制,帮我们轻松实现了这种“承诺”。它不仅封装了底层复杂的事务控制逻辑(比如手动开启、提交、回滚事务),还提供了灵活的配置方式,让开发者能专注于业务逻辑,而不用纠结于事务细节。
|
7月前
|
Java Spring
Spring中事务失效的场景
因为Spring事务是基于代理来实现的,所以某个加了@Transactional的⽅法只有是被代理对象调⽤时, 那么这个注解才会⽣效 , 如果使用的是被代理对象调用, 那么@Transactional会失效 同时如果某个⽅法是private的,那么@Transactional也会失效,因为底层cglib是基于⽗⼦类来实现 的,⼦类是不能重载⽗类的private⽅法的,所以⽆法很好的利⽤代理,也会导致@Transactianal失效 如果在业务中对异常进行了捕获处理 , 出现异常后Spring框架无法感知到异常, @Transactional也会失效
|
2月前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
7月前
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——常见问题总结
本文总结了Spring Boot中使用事务的常见问题,虽然通过`@Transactional`注解可以轻松实现事务管理,但在实际项目中仍有许多潜在坑点。文章详细分析了三个典型问题:1) 异常未被捕获导致事务未回滚,需明确指定`rollbackFor`属性;2) 异常被try-catch“吃掉”,应避免在事务方法中直接处理异常;3) 事务范围与锁范围不一致引发并发问题,建议调整锁策略以覆盖事务范围。这些问题看似简单,但一旦发生,排查难度较大,因此开发时需格外留意。最后,文章提供了课程源代码下载地址,供读者实践参考。
143 0
|
7月前
|
Java 关系型数据库 数据库
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——Spring Boot 事务配置
本文介绍了 Spring Boot 中的事务配置与使用方法。首先需要导入 MySQL 依赖,Spring Boot 会自动注入 `DataSourceTransactionManager`,无需额外配置即可通过 `@Transactional` 注解实现事务管理。接着通过创建一个用户插入功能的示例,展示了如何在 Service 层手动抛出异常以测试事务回滚机制。测试结果表明,数据库中未新增记录,证明事务已成功回滚。此过程简单高效,适合日常开发需求。
936 0
|
7月前
|
Java 数据库 微服务
微服务——SpringBoot使用归纳——Spring Boot事务配置管理——事务相关
本文介绍Spring Boot事务配置管理,阐述事务在企业应用开发中的重要性。事务确保数据操作可靠,任一异常均可回滚至初始状态,如转账、购票等场景需全流程执行成功才算完成。同时,事务管理在Spring Boot的service层广泛应用,但根据实际需求也可能存在无需事务的情况,例如独立数据插入操作。
153 0
|
6月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
399 70