十一.Spring源码剖析-事务源码之@Transactionl解析

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 在上一章我们分析了Spring的AOP的源码,本篇文章是对事务的源码分析,我们都知道事务的管理是基于AOP实现的,所以有了上一篇的铺垫这一章会比较简单一点。事务的源码我会分两章写,一张写Transcational的解析,一张写事务的执行流程。先上一个图,待会儿可以根据这个图来看源码

前言

在上一章我们分析了Spring的AOP的源码,本篇文章是对事务的源码分析,我们都知道事务的管理是基于AOP实现的,所以有了上一篇的铺垫这一章会比较简单一点。

事务的源码我会分两章写,一张写Transcational的解析,一张写事务的执行流程。先上一个图,待会儿可以根据这个图来看源码
在这里插入图片描述

事务配置案例

配置事务管理器,开启注解事务支持

    <!-- 开启事务支持 -->
    <tx:annotation-driven/>

    <!-- 事务管理器 -->
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!-- 配置数据源-->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
    ...省略...
    </bean>

标记方法需要事务

public class UserService ...{
   
   

    //事务注解
    @Transactional
    public void insert(User user){
   
   
        ...
    }

}

事务注解打在方法上,当然也是可以打在类上。

事务注解原理

在Spring中通常有两种方式管理事务,一是使用XML统一配置事务 ,二是通过注解式编程即在对象方法上贴@Trancactional来管理事务,现在用的多的就是注解式编程,所以我们就从这个事务注解开始分析把。

Transactional贴在对象的方法上就可以通过AOP的方式帮我们开启事务,提交事务或是回滚事务操作,不仅简化了我们的工作难度,避免重复事务逻辑处理,同时也减少了代码的侵入,达到代码解耦和的效果。
在这里插入图片描述
事务的管理是基于AOP实现,AOP的原理又是动态代理,也就是说被标记了@Transactional的类都会创建代理类来实现事务增强,创建代理后,方法的真实调用都是走代理对象。那么Spring如何知道要对哪些类哪些方法进行代理?Spring会把 @Transactional 注解作为切点,这样就知道哪些方法需要被代理 。至于代理类的创建是在Bean的实例化过程中完成,在上一篇文章有说道,见:《AOP原理
在这里插入图片描述

事务标签解析器

NamespaceHandlerSupport 注册解析器

因为注解事务支持需要在XML中开启 ,所以对于事务来说可以分为两部分 :一是事务配置解析 ,二是代理创建。在上一章节我们就有提到,对于xml中的所有namespace都有对应的解析器, 在Spring中有一个接口叫 NamespaceHandlerSupport ,它提供了Spring xml配置的namespace的解析支持。
在这里插入图片描述
NamespaceHandlerSupport它有一个子类 TxNaespaceHadler 就是针对于事务的 namespace 处理

public class TxNamespaceHandler extends NamespaceHandlerSupport {
   
   

    static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
    //事务管理器默认的名字
    static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";


    static String getTransactionManagerName(Element element) {
   
   
        return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
                element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
    }


    @Override
    public void init() {
   
   
        registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
        registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
    }

}

AnnotationDrivenBeanDefinitionParser创建AutoProxyCreator

看得出来上面的 init 方法中注册了一个 AnnotationDrivenBeanDefinitionParser 它就是针对于 <tx:annotation-driven/>的解析器,并且负责创建事务管理需要的基础类。

class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
   
   
    AnnotationDrivenBeanDefinitionParser() {
   
   
    }
    //解析元素:Element就是 <tx:annotation-driven/>
 public BeanDefinition parse(Element element, ParserContext parserContext) {
   
   
         //注册事务监听
        this.registerTransactionalEventListenerFactory(parserContext);
        //判断model,默认是proxy,走else
        String mode = element.getAttribute("mode");
        if ("aspectj".equals(mode)) {
   
   
            this.registerTransactionAspect(element, parserContext);
        } else {
   
   
            //创建自动代理创建器(InfrastructureAdvisorAutoProxyCreator)
          AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
        }

        return null;
    }

AopAutoProxyConfigurer 创建事务核心类

这个parse解析方法注册了事务监听器后就判断了mode,默认使用的是proxy代理方式,即调用configureAutoProxyCreator方法,一路跟下去

 /**
     * Inner class to just introduce an AOP framework dependency when actually in proxy mode.
     */
    private static class AopAutoProxyConfigurer {
   
   

        public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
   
   
            //注册一个自动代理创建器 InfrastructureAdvisorAutoProxyCreator
            AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

            String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
            //判断容器中是否已经注册了 internalTransactionAdvisor
            if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
   
   
                Object eleSource = parserContext.extractSource(element);
                //【标记1】注册 TransactionAttributeSource
                // Create the TransactionAttributeSource definition.
                RootBeanDefinition sourceDef = new RootBeanDefinition(
                        "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
                sourceDef.setSource(eleSource);
                sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
                //【标记2】注册 TransactionInterceptor
                // Create the TransactionInterceptor definition.
                RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
                interceptorDef.setSource(eleSource);
                interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
                registerTransactionManager(element, interceptorDef);

                interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
                //【标记3】 注册一个TransactionAttributeSourceAdvisor
                // Create the BeanFactoryTransactionAttributeSourceAdvisor definition.
                RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
                advisorDef.setSource(eleSource);
                advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

                advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
                advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
                if (element.hasAttribute("order")) {
   
   
                    advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
                }
                parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);

                CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
                compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
                compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
                compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
                parserContext.registerComponent(compositeDef);
            }
        }
    }

该方法先是创建了一个 InfrastructureAdvisorAutoProxyCreator 代理创建器 ,然后又注册了 AnnotationTransactionAttributeSourceTransactionInterceptorBeanFactoryTransactionAttributeSourceAdvisor 三个Bean , 且前两个Bean被添加到了 BeanFactoryTransactionAttributeSourceAdvisor 中。

  • InfrastructureAdvisorAutoProxyCreator:是BeanPostProcessor的子类,在Bean的初始化之后调用postProcessAfterInitialization方法,目的就是找出增强器为合适的类创建代理。跟上一章节《AOP原理》做的事情差不多
  • AnnotationTransactionAttributeSource : 是专门用于获取基于注解的Spring声明式事务管理的事务属性的属性源,用来读取@Transational注解并进行相关参数封装,用做后续的事务处理。

    它除了能处理Transactional注解之外,还支持JTA 1.2的javax.transaction.Transactional事务注解以及EJB3的javax.ejb.TransactionAttribute事务注解

  • TransactionInterceptor:该类实现了TransactionAspectSupport , TransactionAspectSupport 中持有 TransactionManager ,拥有处理事务的能力。同时该类还实现了 MethodInterceptor 接口 ,它也作为AOP的拦截器。拦截器链中每个拦截器都有一个invoke方法,该方法就是对某个方法进行事务增强的入口,因此主要看invoke方法的实现逻辑!

  • BeanFactoryTransactionAttributeSourceAdvisor:它是一个Advisor,用来对事务方法做增强,只要被注解@Transationl的方法都会被增强,该Advisor 包含 AnnotationTransactionAttributeSource 和 TransactionInterceptor ,以及 TransactionAttributeSourcePointcut 。

    TransactionAttributeSourcePointcut 是事务属性源匹配器,是BeanFactoryTransactionAttributeSourceAdvisor的切入点,通过它来判断某个bean是否可以被增强

在这里插入图片描述

解析当前方法是否要被代理

InfrastructureAdvisorAutoProxyCreator是一个BeanPostProcessor,当Bean在实例化过程中,会通过AutoProxyCreator的postProcessAfterInitialization方法来决定是否创建代理,其实就是通过BeanFactoryTransactionAttributeSourceAdvisor 来解析判断该类是否被注解了@Transcational来决定是否创建代理 ,见:AbstractAutoProxyCreator#wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   
   
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
   
   
            return bean;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
   
   
            return bean;
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
   
   
            //获取增强器 Advisors
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            if (specificInterceptors != DO_NOT_PROXY) {
   
   
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                //创建代理
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
   
   
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
   
   
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }

AbstractAdvisorAutoProxyCreator查找增强器

通过调用 AbstractAdvisorAutoProxyCreator#findCandidateAdvisors ,查找增强器 ,通过AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply 来匹配当前类适合的增强器,然后为当前Bean创建代理。这个流程在上一章: 《AOP原理》 已经说过,这里就不细细分析了。见:AbstractAdvisorAutoProxyCreator#findEligibleAdvisors


    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   
   
        //查找所有增强器
        List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
        //找到当前beanClass适用的增强器
        List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        this.extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
   
   
            eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
        }

        return eligibleAdvisors;
    }

我们重点来看一下它是如何匹配适合当前Bean的增强器的。见:
AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply

    //搜索能应用于当前beanClass的 Advisors
    protected List<Advisor> findAdvisorsThatCanApply(
            List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
   
   

        ProxyCreationContext.setCurrentProxiedBeanName(beanName);
        try {
   
   
            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }
        finally {
   
   
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }

这里的 candidateAdvisors 就是获取到的增强器 ,其中就包括:BeanFactoryTransactionAttributeSourceAdvisor , beanClass是当前要被创建代理的类,然后走的是AopUtils.findAdvisorsThatCanApply 方法查找能匹配当前类的advisors.一路断点跟下去会走到 AopUtils#canApply

    public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
   
   
        if (advisor instanceof IntroductionAdvisor) {
   
   
            return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
        }

        else if (advisor instanceof PointcutAdvisor) {
   
   
            //转换成 PointcutAdvisor 切点的Advisor
            PointcutAdvisor pca = (PointcutAdvisor) advisor;
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        }
        else {
   
   
            // It doesn't have a pointcut so we assume it applies.
            return true;
        }
    }

AopUtils 查找合适的增强器

继续跟踪 org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class<?>, boolean) 源码:

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
   
   
        Assert.notNull(pc, "Pointcut must not be null");
        //class 过滤器 ,默认直接返回true
        if (!pc.getClassFilter().matches(targetClass)) {
   
   
            return false;
        }
        //方法匹配器,其实就是  BeanFactoryTransactionAttributeSourceAdvisor
        MethodMatcher methodMatcher = pc.getMethodMatcher();
        if (methodMatcher == MethodMatcher.TRUE) {
   
   
            // No need to iterate the methods if we're matching any method anyway...
            return true;
        }

        IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
        if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
   
   
            introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
        }
        //获取到要被创建代理的原生类的 class,并把其接口添加到classes中
        Set<Class<?>> classes = new LinkedHashSet<>();
        if (!Proxy.isProxyClass(targetClass)) {
   
   
            classes.add(ClassUtils.getUserClass(targetClass));
        }
        classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
        //处理classes
        for (Class<?> clazz : classes) {
   
   
        //拿到原生类,或其接口的所有方法声明
            Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
            for (Method method : methods) {
   
   
                //通过 MethodMatcher 匹配,走的是 TransactionAttributeSourcePointcut#matches方法
                if (introductionAwareMethodMatcher != null ?
                        introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                        methodMatcher.matches(method, targetClass)) {
   
   
                    return true;
                }
            }
        }

        return false;
    }

该方法的作用是匹配给定的切入点是否完全适用于给定的类,通过MethodMatcher 来匹配,这里的MethodMatcher 本身就是PointBeanFactoryTransactionAttributeSourceAdvisor,它通过父类TransactionAttributeSourcePointcut#matches完成匹配,如下:

TransactionAttributeSourcePointcut 查找@Transactional注解

下面是 TransactionAttributeSourcePointcut 进行匹配的源码:

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
   
   

    @Override
    public boolean matches(Method method, @Nullable Class<?> targetClass) {
   
   
        if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
   
   
            return false;
        }
        //获取 BeanFactoryTransactionAttributeSourceAdvisor 中的AnnotationTransactionAttributeSource
        TransactionAttributeSource tas = getTransactionAttributeSource();
        //判断TransactionAttribute不为空,说明该targetClass的method是有事务注解的
        return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
    }

这里getTransactionAttributeSource();方法由子类BeanFactoryTransactionAttributeSourceAdvisor 来实现,目的是获取TransactionAttributeSource 对象,然后调用tas.getTransactionAttribute获取TransactionAttribute,不为空说明方法是支持@Transational的。

tas.getTransactionAttribute 方法中会先通过类名和方法名构建一个key,从缓存中 attributeCache 获取TransactionAttribute,如果没有,就通过AnnotationTransactionAttributeSource#determineTransactionAttribute 去解析当前Method 的@Transactional封装成 TransactionAttribute,并装入缓存。源码如下;

org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#getTransactionAttribute

public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   
   
        if (method.getDeclaringClass() == Object.class) {
   
   
            return null;
        }

        // First, see if we have a cached value.
        //构建一个缓存key
        Object cacheKey = getCacheKey(method, targetClass);
        //从缓存中获取TransactionAttribute 
        TransactionAttribute cached = this.attributeCache.get(cacheKey);
        if (cached != null) {
   
   
            // Value will either be canonical value indicating there is no transaction attribute,
            // or an actual transaction attribute.
            if (cached == NULL_TRANSACTION_ATTRIBUTE) {
   
   
                return null;
            }
            else {
   
   
            //返回缓存中的TransactionAttribute
                return cached;
            }
        }
        else {
   
   
            // We need to work it out.
            //查找和解析method的事务注解,封装成TransactionAttribute
            TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
            // Put it in the cache.
            if (txAttr == null) {
   
   
                this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
            }
            else {
   
   
                String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
                if (txAttr instanceof DefaultTransactionAttribute) {
   
   
                    ((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
                }
                if (logger.isDebugEnabled()) {
   
   
                    logger.debug("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
                }
                //把 TransactionAttribute  放入缓存attributeCache
                this.attributeCache.put(cacheKey, txAttr);
            }
            return txAttr;
        }
    }

我们看一下 computeTransactionAttribute 方法的源码

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   
   
        // Don't allow no-public methods as required.
        //默认只能是public方法进行事务代理,但是可以通过allowPublicMethodsOnly方法修改
        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
   
   
            return null;
        }

        // The method may be on an interface, but we need attributes from the target class.
        // If the target class is null, the method will be unchanged.
        //有可能找到的是接口方法,但是需要的是实现类的方法
        Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

        // First try is the method in the target class.
        //【重要】首先从方法上找事务注解,有就返回,没有再找类上的事务注解,所以方法上的事务注解优先级高
        TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
        if (txAttr != null) {
   
   
            return txAttr;
        }

        // Second try is the transaction attribute on the target class.
        //[重要]然后从当前类上找注解
        txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
        if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
   
   
            return txAttr;
        }
        //如果最终的目标方法和当前方法不一致,从当前方法上找
        if (specificMethod != method) {
   
   
            //回退是看原方法
            // Fallback is to look at the original method.
            txAttr = findTransactionAttribute(method);
            if (txAttr != null) {
   
   
                return txAttr;
            }
            // Last fallback is the class of the original method.
            //最后一个回退是原始方法的类
            txAttr = findTransactionAttribute(method.getDeclaringClass());
            if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
   
   
                return txAttr;
            }
        }
        //实在找不到,返回一个null,该方法不会被代理
        return null;
    }

首先从方法上找事务注解,如果没有就从类上面去找,如果始终找不到,就返回一个null,该方法不会被代理。最终代码来到AnnotationTransactionAttributeSource#determineTransactionAttribute

    protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
   
   
        for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
   
   
            //委托 TransactionAnnotationParser(SpringTransactionAnnotationParser) 去解析事务注解
            TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
            if (attr != null) {
   
   
                return attr;
            }
        }
        return null;
    }

查找事务属性工作交给 AnnotationTransactionAttributeSource 完成,它委托了TransactionAnnotationParser#parseTransactionAnnotation来实现。默认使用解析器SpringTransactionAnnotationParser它支持Spring的@Transactional注解。

SpringTransactionAnnotationParser 解析 @Transcational注解

继续跟踪 SpringTransactionAnnotationParser#parseTransactionAnnotation 源码如下:

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
   
   
        //通过AnnotatedElementUtils查找 方法上的 Transactional注解,解析并封装成AnnotationAttributes 
        //查找方法或者类上的@Transactional注解,没找到,那么会继续在父类的方法上,和类上找。
        //最终将使用找到的第一个注解数据
        AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
                element, Transactional.class, false, false);
        if (attributes != null) {
   
   
            return parseTransactionAnnotation(attributes);
        }
        else {
   
   
            return null;
        }
    }

找到AnnotationAttributes 之后调用parseTransactionAnnotation进行解析,把事务的配置封装成RuleBasedTransactionAttribute返回,源码如下

protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
   
   
        RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

        Propagation propagation = attributes.getEnum("propagation");
        rbta.setPropagationBehavior(propagation.value());
        Isolation isolation = attributes.getEnum("isolation");
        rbta.setIsolationLevel(isolation.value());
        rbta.setTimeout(attributes.getNumber("timeout").intValue());
        rbta.setReadOnly(attributes.getBoolean("readOnly"));
        rbta.setQualifier(attributes.getString("value"));

        List<RollbackRuleAttribute> rollbackRules = new ArrayList<>();
        for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) {
   
   
            rollbackRules.add(new RollbackRuleAttribute(rbRule));
        }
        for (String rbRule : attributes.getStringArray("rollbackForClassName")) {
   
   
            rollbackRules.add(new RollbackRuleAttribute(rbRule));
        }
        for (Class<?> rbRule : attributes.getClassArray("noRollbackFor")) {
   
   
            rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
        }
        for (String rbRule : attributes.getStringArray("noRollbackForClassName")) {
   
   
            rollbackRules.add(new NoRollbackRuleAttribute(rbRule));
        }
        rbta.setRollbackRules(rollbackRules);

        return rbta;
    }

总结

本篇文章主要是判断类是否有被注解@Transcationl从而决定是否可用被代理,整体流程如下:

  1. 在 TxNamespaceHandler 注册了AnnotationDrivenBeanDefinitionParser用来解析事务注解配置
  2. 在AnnotationDrivenBeanDefinitionParser中创建 InfrastructureAdvisorAutoProxyCreator,其本身是个BeanPostPorcessor,还创建了 TransactionAttributeSource , TransactionInterceptor , TransactionAttributeSourceAdvisor
  3. 在Bean实例化的过程中调用InfrastructureAdvisorAutoProxyCreator#postProcessAfterInitialization 来解析Bean是否有@Transational,从而判断是否要进行增强创建代理。
  4. 在AutoProxyCreator 内部的 AopUtils#canApply 方法中通过 BeanFactoryTransactionAttributeSourceAdvisor的TransactionAttributeSourcePointcut切入点的matches方法中进行解析方法上的@Transactional 来决定是否要增强。
  5. 该方法获取到BeanFactoryTransactionAttributeSourceAdvisor 中的AnnotationTransactionAttributeSource,调用其getTransactionAttribute来解析。内部通过 SpringTransactionAnnotationParser#parseTransactionAnnotation来解析 方法上的@Transactional,如果方法上没有就去类上找,或者去父类的方法和类上找。
  6. 如果找到了就缓存到AbstractFallbackTransactionAttributeSource的attributeCache中,如果没找到说明这类不需要被事务增强。

文章结束,喜欢就给个好评吧,你的肯定是我最大的动力哦!!!

相关文章
|
10天前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
10天前
|
存储 设计模式 算法
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
行为型模式用于描述程序在运行时复杂的流程控制,即描述多个类或对象之间怎样相互协作共同完成单个对象都无法单独完成的任务,它涉及算法与对象间职责的分配。行为型模式分为类行为模式和对象行为模式,前者采用继承机制来在类间分派行为,后者采用组合或聚合在对象间分配行为。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象行为模式比类行为模式具有更大的灵活性。 行为型模式分为: • 模板方法模式 • 策略模式 • 命令模式 • 职责链模式 • 状态模式 • 观察者模式 • 中介者模式 • 迭代器模式 • 访问者模式 • 备忘录模式 • 解释器模式
【23种设计模式·全精解析 | 行为型模式篇】11种行为型模式的结构概述、案例实现、优缺点、扩展对比、使用场景、源码解析
|
10天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。 结构型模式分为以下 7 种: • 代理模式 • 适配器模式 • 装饰者模式 • 桥接模式 • 外观模式 • 组合模式 • 享元模式
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
10天前
|
设计模式 存储 安全
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
创建型模式的主要关注点是“怎样创建对象?”,它的主要特点是"将对象的创建与使用分离”。这样可以降低系统的耦合度,使用者不需要关注对象的创建细节。创建型模式分为5种:单例模式、工厂方法模式抽象工厂式、原型模式、建造者模式。
【23种设计模式·全精解析 | 创建型模式篇】5种创建型模式的结构概述、实现、优缺点、扩展、使用场景、源码解析
|
29天前
|
PyTorch Shell API
Ascend Extension for PyTorch的源码解析
本文介绍了Ascend对PyTorch代码的适配过程,包括源码下载、编译步骤及常见问题,详细解析了torch-npu编译后的文件结构和三种实现昇腾NPU算子调用的方式:通过torch的register方式、定义算子方式和API重定向映射方式。这对于开发者理解和使用Ascend平台上的PyTorch具有重要指导意义。
|
30天前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
53 2
|
11天前
|
安全 搜索推荐 数据挖掘
陪玩系统源码开发流程解析,成品陪玩系统源码的优点
我们自主开发的多客陪玩系统源码,整合了市面上主流陪玩APP功能,支持二次开发。该系统适用于线上游戏陪玩、语音视频聊天、心理咨询等场景,提供用户注册管理、陪玩者资料库、预约匹配、实时通讯、支付结算、安全隐私保护、客户服务及数据分析等功能,打造综合性社交平台。随着互联网技术发展,陪玩系统正成为游戏爱好者的新宠,改变游戏体验并带来新的商业模式。
|
3月前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
254 2
|
10天前
|
Java 数据库连接 Maven
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
自动装配是现在面试中常考的一道面试题。本文基于最新的 SpringBoot 3.3.3 版本的源码来分析自动装配的原理,并在文未说明了SpringBoot2和SpringBoot3的自动装配源码中区别,以及面试回答的拿分核心话术。
最新版 | 深入剖析SpringBoot3源码——分析自动装配原理(面试常考)
|
17天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
67 14

推荐镜像

更多