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的基础吗。


相关文章
|
17天前
|
Java 应用服务中间件 Nacos
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
Spring Cloud 常用各个组件详解及实现原理(附加源码+实现逻辑图)
31 0
|
18天前
|
Java 数据库 开发者
|
20天前
|
监控 数据可视化 安全
一套成熟的Spring Cloud智慧工地平台源码,自主版权,开箱即用
这是一套基于Spring Cloud的智慧工地管理平台源码,具备自主版权,易于使用。平台运用现代技术如物联网、大数据等改进工地管理,服务包括建设各方,提供人员、车辆、视频监控等七大维度的管理。特色在于可视化管理、智能报警、移动办公和分布计算存储。功能涵盖劳务实名制管理、智能考勤、视频监控AI识别、危大工程监控、环境监测、材料管理和进度管理等,实现工地安全、高效的智慧化管理。
|
2天前
|
SQL Java 关系型数据库
Spring 事务
Spring 事务
6 1
|
2天前
|
存储 前端开发 Java
Spring Boot自动装配的源码学习
【4月更文挑战第8天】Spring Boot自动装配是其核心机制之一,其设计目标是在应用程序启动时,自动配置所需的各种组件,使得应用程序的开发和部署变得更加简单和高效。下面是关于Spring Boot自动装配的源码学习知识点及实战。
12 1
|
4天前
|
传感器 人工智能 前端开发
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
智慧校园电子班牌,坐落于班级的门口,适合于各类型学校的场景应用,班级学校日常内容更新可由班级自行管理,也可由学校统一管理。让我们一起看看,电子班牌有哪些功能呢?
45 4
JAVA语言VUE2+Spring boot+MySQL开发的智慧校园系统源码(电子班牌可人脸识别)Saas 模式
|
5天前
|
Java 数据库连接 数据库
Spring事务简介,事务角色,事务属性
Spring事务简介,事务角色,事务属性
15 2
|
9天前
|
Java 数据库连接 数据库
16:事务-Java Spring
16:事务-Java Spring
25 5
|
10天前
|
消息中间件 Java 关系型数据库
Spring事务与分布式事务
这篇文档介绍了事务的概念和数据库事务的ACID特性:原子性、一致性、隔离性和持久性。在并发环境下,事务可能出现更新丢失、脏读和不可重复读等问题,这些问题通过设置事务隔离级别(如读未提交、读已提交、可重复读和序列化)来解决。Spring事务传播行为有七种模式,影响嵌套事务的执行方式。`@Transactional`注解用于管理事务,其属性包括传播行为、隔离级别、超时和只读等。最后提到了分布式事务,分为跨库和跨服务两种情况,跨服务的分布式事务通常通过最终一致性策略,如消息队列实现。
|
11天前
|
设计模式 安全 Java
【初学者慎入】Spring源码中的16种设计模式实现
以上是威哥给大家整理了16种常见的设计模式在 Spring 源码中的运用,学习 Spring 源码成为了 Java 程序员的标配,你还知道Spring 中哪些源码中运用了设计模式,欢迎留言与威哥交流。