SpringAop学习笔记(四)——@Transactional

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群版 2核4GB 100GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用版 2核4GB 50GB
简介: SpringAop学习笔记(四)——@Transactional

正文


一、入口


package com.xiaojie.spring;
import com.mysql.cj.jdbc.MysqlDataSource;
import org.springframework.context.annotation.*;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
/*
 * 
 * @param null 
 * 配置类
 * @author xiaojie 
 * @date 2021/8/24 
 * @return 
 */
@Configuration
@ComponentScan("com.xiaojie")
@EnableTransactionManagement
public class Config {
 /*
  *  
  * 加载数据源
  * @author xiaojie 
  * @date 2021/8/24
  * @return javax.sql.DataSource
  */
    @Bean
    DataSource dataSource(){
        MysqlDataSource mysqlDataSource = new MysqlDataSource();
        mysqlDataSource.setURL("jdbc:mysql://127.0.0.1:3306/order?useUnicode=true&characterEncoding=UTF-8&rewriteBatchedStatements=true&allowMultiQueries=true&serverTimezone=Asia/Shanghai");
        mysqlDataSource.setUser("root");
        mysqlDataSource.setPassword("root");
//        mysqlDataSource.setDatabaseName("order");
        return mysqlDataSource;
    }
    /*
     *  加载事务管理器
     * @author xiaojie 
     * @date 2021/8/24 
     * @return org.springframework.transaction.PlatformTransactionManager
     */
    @Bean
    PlatformTransactionManager platformTransactionManager(){
        return new DataSourceTransactionManager(dataSource());
    }
    /*
     *数据库连接
     * @author xiaojie 
     * @date 2021/8/24 
     * @return org.springframework.jdbc.core.JdbcTemplate
     */
    @Bean
    JdbcTemplate jdbcTemplate(){
    return new JdbcTemplate(dataSource());
    }
}


@EnableTransactionManagement 为事务的入口


二、流程图


111.png


三 、源码


AutoProxyRegistrar


            //默认是代理模式
            if (mode == AdviceMode.PROXY) {
                    //注册InfrastructureAdvisorAutoProxyCreator.class类到ioc容器
          AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
          if ((Boolean) proxyTargetClass) {
            AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            return;
        }
      }


AopConfigUtils


private static BeanDefinition registerOrEscalateApcAsRequired(
      Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
      BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
      if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
        int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
        int requiredPriority = findPriorityForClass(cls);
        if (currentPriority < requiredPriority) {
          apcDefinition.setBeanClassName(cls.getName());
        }
      }
      return null;
    }
    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
        //AUTO_PROXY_CREATOR_BEAN_NAME=org.springframework.aop.config.internalAutoProxyCreator
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
  }


上述注册完之后会将InfrastructureAdvisorAutoProxyCreator.class类注入到IOC中


beanId:org.springframework.aop.config.internalAutoProxyCreator


Class:InfrastructureAdvisorAutoProxyCreator.class


555.jpg


由类图InfrastructureAdvisorAutoProxyCreator.class继承了BeanPostProcessor同样会执行前置增强或者后置增强。


ProxyTransactionManagementConfiguration.class


//将TransactionInterceptor 类注入到IOC 
@Bean
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
    TransactionInterceptor interceptor = new TransactionInterceptor();
    interceptor.setTransactionAttributeSource(transactionAttributeSource);
    if (this.txManager != null) {
      interceptor.setTransactionManager(this.txManager);
    }
    return interceptor;
  }


再看BeanPostProcessor后置增强方法


555.jpg


然后就会发现跟AOP的代码是一样的


JdkDynamicAopProxy下invoke()


public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object oldProxy = null;
    boolean setProxyContext = false;
        .........省略
        // Get the interception chain for this method.
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
      // Check whether we have any advice. If we don't, we can fallback on direct
      // reflective invocation of the target, and avoid creating a MethodInvocation.
      if (chain.isEmpty()) {
        // We can skip creating a MethodInvocation: just invoke the target directly
        // Note that the final invoker must be an InvokerInterceptor so we know it does
        // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
        Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
        retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
        // We need to create a method invocation...
        MethodInvocation invocation =
            new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
        // Proceed to the joinpoint through the interceptor chain.
                //由此进入proceed()方法
        retVal = invocation.proceed();
      }
    .........省略
  }


ReflectiveMethodInvocation


555.jpg


public Object proceed() throws Throwable {
    // We start with an index of -1 and increment early.
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      return invokeJoinpoint();
    }
    Object interceptorOrInterceptionAdvice =
        this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      // Evaluate dynamic method matcher here: static part will already have
      // been evaluated and found to match.
      InterceptorAndDynamicMethodMatcher dm =
          (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
      Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
      if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
        return dm.interceptor.invoke(this);
      }
      else {
        // Dynamic matching failed.
        // Skip this interceptor and invoke the next in the chain.
        return proceed();
      }
    }
    else {
      // It's an interceptor, so we just invoke it: The pointcut will have
      // been evaluated statically before this object was constructed.
            //此处用到了责任链设计模式+递归思想实现所有的通知增强
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
  }


MethodInterceptor


Object invoke(@Nonnull MethodInvocation invocation) throws Throwable;


555.jpg

TransactionInterceptor类下的invoke()方法


   protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, TransactionAspectSupport.InvocationCallback invocation) throws Throwable {
       ......省略
         TransactionAspectSupport.TransactionInfo txInfo = this.createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
                Object retVal;
                try {
                    //执行目标方法
                    retVal = invocation.proceedWithInvocation();
                } catch (Throwable var20) {
                    //发生异常 则执行事务回滚
                    this.completeTransactionAfterThrowing(txInfo, var20);
                    throw var20;
                } finally {
                //将当前事务归还ThreadLocal<TransactionAspectSupport.TransactionInfo>
                    this.cleanupTransactionInfo(txInfo);
                }
                if (retVal != null && vavrPresent &&             TransactionAspectSupport.VavrDelegate.isVavrTry(retVal)) {
                    TransactionStatus status = txInfo.getTransactionStatus();
                    if (status != null && txAttr != null) {
                        retVal = TransactionAspectSupport.VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
                    }
                }
                //提交事务
                this.commitTransactionAfterReturning(txInfo);
                return retVal;
       .........省略
    }


Spring 版本为5.3.9

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2月前
|
SQL Java 数据库
Transactional注解讲解及使用
事务是数据库操作的一组集合,它作为一个工作单元,要求所有操作要么全部成功,要么全部失败。事务的四个基本特性是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。
|
3月前
|
关系型数据库 Java MySQL
一篇文章学会使用@Transactional
一篇文章学会使用@Transactional
30 0
|
3月前
|
Java Spring 容器
SpringAop
SpringAop
42 0
|
9月前
|
SQL Java 数据库连接
@Transactional
@Transactional
85 0
|
Java 数据库 Spring
@Transactional注解超详细
@Transactional注解超详细
683 0
|
11月前
|
XML 监控 Java
SpringAOP介绍与使用
SpringAOP介绍与使用
58 0
|
Java Spring
|
数据安全/隐私保护
SpringAOP(四)
SpringAOP(四)
|
数据安全/隐私保护
SpringAOP(二)
SpringAOP(二)
|
Java 数据库连接 数据库
SpringAOP(三)
SpringAOP(三)