Spring 事务初始化源码分析

本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

原文链接:blog.ouyangsihai.cn >> Spring 事务初始化源码分析

前言

在上篇文章  中详细介绍了 Spring 事务的使用过程,今天就来看下 Spring 事务是如何来实现,比如 Spring 事务在初始化的时候做了什么, Spring 事务是如何进行事务的提交和回滚的;为了避免篇幅太长,所以分开两篇文章进行分析,这篇文章先来分析下 Spring 事务是如何初始化的,在初始化的时候做了什么。

注册 InfrastructureAdvisorAutoProxyCreator

我们知道,想要使用 Spring 事务,就得开启 Spring 的事务功能,如果是配置文件的方式,则需要在配置文件中配置 tx:annotation-driven / 标签,那么分析 Spring 事务初始化就从解析该标签开始。

TxNamespaceHandler 类的 init 方法中可以看到解析该标签的代码逻辑:


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

所以,当在解析   tx:annotation-driven / 标签的时候,会使用 AnnotationDrivenBeanDefinitionParser 类的 parse 方法来进行解析:


// AnnotationDrivenBeanDefinitionParser.java

public BeanDefinition parse(Element element, ParserContext parserContext) {
    this.registerTransactionalEventListenerFactory(parserContext);
    String mode = element.getAttribute("mode");
    if ("aspectj".equals(mode)) {
        // aspectj 模式
        this.registerTransactionAspect(element, parserContext);
    } else {
        // proxy 模式 
    AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
    }
    return null;
}

接下来看下 proxy模式,即默认模式的解析;即用的是它的内部类 AopAutoProxyConfigurer configureAutoProxyCreator 方法进行解析:


public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
    AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
    // ...............
}

在该方法中,第一行就是进行注册 ** InfrastructureAdvisorAutoProxyCreator**,还有其他的bean的注册,这里先不管;先来看下注册过程:


public static void registerAutoProxyCreatorIfNecessary(ParserContext parserContext, Element sourceElement) {
    // 注册
    BeanDefinition beanDefinition = AopConfigUtils.registerAutoProxyCreatorIfNecessary(
            parserContext.getRegistry(), parserContext.extractSource(sourceElement));
    // 处理proxy-target-class和 expose-proxy属性
    useClassProxyingIfNecessary(parserContext.getRegistry(), sourceElement);
    // ......
}

这里和 Spring AOP 的处理流程是一样的,先是注册目标 bean,再处理 proxy-target-class expose-proxy 属性,可以参考: Spring AOP 注解方式源码解析 (https://my.oschina.net/mengyuankan/blog/2995521)

注册 InfrastructureAdvisorAutoProxyCreator.class


public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry,Object source) {
    return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}

private static BeanDefinition registerOrEscalateApcAsRequired(Class? cls, 
                BeanDefinitionRegistry registry,Object source) {
    // 处理优先级
    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);
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}

关于该 bean 的作用下面分析,在 AopAutoProxyConfigurer configureAutoProxyCreator 方法中除了注册该 bean,还注册了三个 bean,这三个 bean 用来支撑 Spring 的整个事务功能:


public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
    // 注册 InfrastructureAdvisorAutoProxyCreator
    AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
    // 事务AdvisorBeanName
    String txAdvisorBeanName = "org.springframework.transaction.config.internalTransactionAdvisor";
    if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
        // 注册 AnnotationTransactionAttributeSource
        Object eleSource = parserContext.extractSource(element);
        RootBeanDefinition sourceDef = new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
        sourceDef.setSource(eleSource);
        sourceDef.setRole(2);
        String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
        // 注册 TransactionInterceptor
        RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
        interceptorDef.setSource(eleSource);
        interceptorDef.setRole(2);
        AnnotationDrivenBeanDefinitionParser.registerTransactionManager(element, interceptorDef);
        interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
        String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
        // 注册 BeanFactoryTransactionAttributeSourceAdvisor
        RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
        advisorDef.setSource(eleSource);
        advisorDef.setRole(2);
        // 并把上面注册的两个bean当作该bean的属性
        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);
        // 注册其他的事件通知组件
    }
}

在这里注册的三个 bean:

  • `BeanFactoryTransactionAttributeSourceAdvisor`
  • `AnnotationTransactionAttributeSource`
  • `TransactionInterceptor`
  • 主要是用来执行目标方法,事务的提交和回滚的.

    这三个 bean 关系如下:

    Spring 事务初始化源码分析

    InfrastructureAdvisorAutoProxyCreator

    这个类是什么意思呢?它有什么用呢?按照类名来理解就是 基础的 Advisor 自动代理创建器,对于自定义的 Advisor,则不用它来创建,它的类图如下:

    Spring 事务初始化源码分析

    可以看到它实现了 BeanPostProcessor 接口,而在前面分析 Spring 相关源码的时候知道,该接口是 Spring 提供了一个扩展接口,有两个方法:

    
    public interface BeanPostProcessor {
        // bean 初始化之前执行
        default Object postProcessBeforeInitialization(Object bean, String beanName){
            return bean;
        }
        // bean 初始化之后执行
        default Object postProcessAfterInitialization(Object bean, String beanName) {
            return bean;
        }
    }
    

    所以,当我们定义的一个 bean 初始化完成后,就会执行 postProcessAfterInitialization 方法,而 InfrastructureAdvisorAutoProxyCreator 类实现了该方法:

    
    public Object postProcessAfterInitialization(Object bean, String beanName) {
        if (bean != null) {
            // 根据 beanClassName 和 beanName 创建一个key
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                // 包装 bean
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
    
    // 包装bean
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        // 已经处理过了,直接返回
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        // 该 bean不需要增强,直接返回
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        // 是否是Advice.class, Pointcut.class, Advisor.class, AopInfrastructureBean.class 这几个类,如果是
        // 这几个类,或者该bean需要跳过的,则直接返回
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
        // 如果有增强,则创建代理
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        if (specificInterceptors != DO_NOT_PROXY) {
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            // 创建代理
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            // 返回代理
            return proxy;
        }
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
    
    // 创建代理
    protected Object createProxy(Class? beanClass, String beanName,
             Object[] specificInterceptors, TargetSource targetSource) {
        // ....
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);
        if (!proxyFactory.isProxyTargetClass()) {
            if (shouldProxyTargetClass(beanClass, beanName)) {
                // CGLIB 代理
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                // JDK接口代理
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
        // 创建代理
        return proxyFactory.getProxy(getProxyClassLoader());
    }
    
    // 真正创建代理
    public Object getProxy(ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }
    protected final synchronized AopProxy createAopProxy() {
        //.....
        return getAopProxyFactory().createAopProxy(this);
    }
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        // 判断 CGLIB 代理和 JDK 代理的条件
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class? targetClass = config.getTargetClass();
            // JDK 代理
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            // CGLIB 代理
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            // JDK 代理
            return new JdkDynamicAopProxy(config);
        }
    }
    

    上述的这段代码,当我们的 bean 初始化完成后,就会为该 bean 创建代理,创建代理的时候,根据配置条件创建 JDK 动态代理或者 CGLIB 代理

    Spring 代理创建参考: Spring AOP 创建代理的源码解析(https://my.oschina.net/mengyuankan/blog/2995754)

    但是,是不是所有的 bean 都会创建代理呢,不是的,在包装 bean 的方法 wrapIfNecessary 中,会去查找该 bean 对应的增强,如果有相应的增强,则才会去创建代理,所以说在创建代理之前,会先去查找该 bean对应的增强(拦截器),在 wrapIfNecessary 方法中有该代码:

    
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    

    对于 Spring 事务来说,该方法返回 specificInterceptors 不可能为空,所以才会走后面创建代理的逻辑。
    接下来看下该方法的实现过程,即查询对应 class 或 method 的增强器。

    查询对应 class 或 method 的增强器

    getAdvicesAndAdvisorsForBean方法中,第一步,要找出符合条件的增强器,第二步,需要判断增强器是否符合要求。

    
    protected Object[] getAdvicesAndAdvisorsForBean(Class? beanClass, String beanName,TargetSource targetSource) {
        // 根据 className 和 beanName 找出符合条件的增强器
        ListAdvisor advisors = findEligibleAdvisors(beanClass, beanName);
        if (advisors.isEmpty()) {
            return DO_NOT_PROXY;
        }
        return advisors.toArray();
    }
    
    // 找出增强器
    protected ListAdvisor findEligibleAdvisors(Class? beanClass, String beanName) {
        //查找增强器
        ListAdvisor candidateAdvisors = findCandidateAdvisors();
        //判断增强器是否符合条件
        ListAdvisor eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        //.......
        return eligibleAdvisors;
    }
    

    查找增强器 findCandidateAdvisors

    
    protected ListAdvisor findCandidateAdvisors() {
        return this.advisorRetrievalHelper.findAdvisorBeans();
    }
    
    public ListAdvisor findAdvisorBeans() {
        String[] advisorNames = this.cachedAdvisorBeanNames;
        if (advisorNames == null) {
            // 获取所有 Advisor.class 类 
            // 在前面注册的 bean:BeanFactoryTransactionAttributeSourceAdvisor 也是一个 Advisor,
            // 所以,在这里该 bean 会被提取出来,后续一起植入代理
            advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false);
            this.cachedAdvisorBeanNames = advisorNames;
        }
        ListAdvisor advisors = new ArrayList();
        for (String name : advisorNames) {
           // 判断增强器bean是否符合条件,这里返回true 
           if (isEligibleBean(name)) {
             if (this.beanFactory.isCurrentlyInCreation(name)) {
                //跳过正在创建的增强器
             }
             else {
                advisors.add(this.beanFactory.getBean(name, Advisor.class));
              }
           }
        }
        return advisors;
    }
    

    查找所有的增强器,就是查找 Advisor.class 类,
    这里要说明一下,在前面注册的 bean ** BeanFactoryTransactionAttributeSourceAdvisor**,它也是一个 Advisor,所以在获取所有的   Advisor.class 类的时候,也会把该 bean 提取出来;此外,该 bean还拥有 ** AnnotationTransactionAttributeSource**和 TransactionInterceptor 这两个 bean,后面会一起被织入代理。

    当查找到所有的增强后,需要判断哪些增强符合我们的目标 bean,对应方法 findAdvisorsThatCanApply,判断的标准很简单,就是去目标类的方法中查找是否存在事务注解 @Transactional,如果存在则满足。

    
    public static ListAdvisor findAdvisorsThatCanApply(ListAdvisor candidateAdvisors, Class? clazz) {
        // 用来存放符合条件的增强
        ListAdvisor eligibleAdvisors = new ArrayList();
        // 处理引介增强
        for (Advisor candidate : candidateAdvisors) {
            if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                eligibleAdvisors.add(candidate);
            }
        }
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();
        for (Advisor candidate : candidateAdvisors) {
            if (candidate instanceof IntroductionAdvisor) {
                // 在处理引介增强时已经处理过了
                continue;
            }
            // 普通的bean
            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }
        return eligibleAdvisors;
    }
    

    在这里,如果增强器满足我们的目标 bean,则会返回增强,之后会对目标 bean创建代理,并把增强织入到代理中。

    判断是否满足,使用 canApply方法进行判断

    解析@Transactional

    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) {
            /// pca=BeanFactoryTransactionAttributeSourceAdvisor
            PointcutAdvisor pca = (PointcutAdvisor) advisor;
            //pca.getPointcut()=TransactionAttributeSourcePointcut
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        }
        else {
            return true;
        }
    }
    

    对于一个事务 bean 来说,该增强 Advisor 就是前面注册的   BeanFactoryTransactionAttributeSourceAdvisor,而该 bean 实现了 PointcutAdvisor 接口,所以会通过 第二个 if 判断;之后 通过 getPointcut 得到 TransactionAttributeSourcePointcut 对象继续调用重载的 canApply 方法如下:

    
    public static boolean canApply(Pointcut pc, Class? targetClass, boolean hasIntroductions) {
        // 获取方法匹配器
        // 此时的匹配器是 TransactionAttributeSourcePointcut
        MethodMatcher methodMatcher = pc.getMethodMatcher();
        // 如果可以匹配所有方法,则不再循环方法进行判断
        if (methodMatcher == MethodMatcher.TRUE) {
            return true;
        }
        // 存放目标类和目标类所有的接口
        SetClass? classes = new LinkedHashSet();
        if (!Proxy.isProxyClass(targetClass)) {
            classes.add(ClassUtils.getUserClass(targetClass));
        }
        classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
        // 遍历目标类和目标类所有的接口下的方法,
        // 如果有任何一个方法能够符合增强器的要求,即有@Transactional注解,则直接返回
        for (Class? clazz : classes) {
          Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
          for (Method method : methods) {
            if (introductionAwareMethodMatcher != null ? 
              introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
              // 匹配方法是否满足条件
               methodMatcher.matches(method, targetClass)) {
            return true;
            }
          }
        }
        return false;
    

    到这里,只看到了根据方法去判断是否符合增强器,没有根据类来和接口判断,因为事务注解 @Transactional 可以放在类或接口上,对其下的所有 public方法有用;其实,对类和接口的判断条件在是在 matcher 方法里面,调用的使用 TransactionAttributeSourcePointcut mathcer 方法如下:

    
    public boolean matches(Method method, Class? targetClass) {
        // .....
        TransactionAttributeSource tas = getTransactionAttributeSource();
        return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
    }
    

    这里判断是否满足条件,就是对应的方法上是否有 @Transactional 注解。
    这里的 tas 就是 AnnotationTransactionAttributeSource,即在文章开头注册的那三个 bean 之一,它的 getTransactionAttribute 如下,去获取事务属性:

    
    public TransactionAttribute getTransactionAttribute(Method method, Class? targetClass) {
        // 忽略 Object 的方法
        if (method.getDeclaringClass() == Object.class) {
            return null;
        }
        // 根据method和class来创建key
        Object cacheKey = getCacheKey(method, targetClass);
        // 根据key查询事务,
        TransactionAttribute cached = this.attributeCache.get(cacheKey);
        if (cached != null) {
           //...
           // 已经判断过了
           return cached;
        }
        else {
           TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
           //....
           return txAttr;
        }
    }
    

    computeTransactionAttribute 方法如下:

    
    protected TransactionAttribute computeTransactionAttribute(Method method, Class? targetClass) {
        // 不是public方法,则跳过
        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
            return null;
        }
        // 实现类的方法
        Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
    
        // 首先在实现类的方法上查询注解,查询到,则直接返回
        TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
        if (txAttr != null) {
            return txAttr;
        }
    
        // 如果在实现类对应方法上找不到注解,则在方法的实现类上查找注解,找到直接返回
        txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
        if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
            return txAttr;
        }
        // 存在接口
        if (specificMethod != method) {
            // 在接口方法上查找注解,找到直接返回
            txAttr = findTransactionAttribute(method);
            if (txAttr != null) {
                return txAttr;
            }
            // 如果在接口方法上找不到注解,则在接口上查找注解
            txAttr = findTransactionAttribute(method.getDeclaringClass());
            if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
                return txAttr;
            }
        }
        return null;
    }
    

    在上述的 computeTransactionAttribute 方法中,可以看到,去查找是一个事务方法上的注解,首先在实现类的方法上查找,找到直接返回,如果还找不到,则在实现类上查找注解;如果在实现类上找不到,再到接口上的方法里面去找,如果接口方法还找不到,则再接口上查找;所以,在这里可以看到,放在类或接口上事务注解可以作用于其下的所有 public 方法,且 方法上的事务注解要优先于类或接口上的注解,即如果再类,接口和方法上都加上事务注解,则会以方法上的注解为准,其次是 类,最后才是接口。

    之后,就是去解析注解的属性,对应方法为: findTransactionAttribute:

    
    protected TransactionAttribute findTransactionAttribute(Method method) {
        return determineTransactionAttribute(method);
    }
    protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
        // 事务注解解析器
        for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
            TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
            if (attr != null) {
                return attr;
            }
        }
        return null;
    }
    
    // 方法上获取 Transactional 注解
    public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
        // 在方法上获取 Transactional 注解
        AnnotationAttributes attributes =
            AnnotatedElementUtils.findMergedAnnotationAttributes(element, Transactional.class, false, false);
        if (attributes != null) {
            // 解析 Transactional 注解属性
            return parseTransactionAnnotation(attributes);
        }
        else {
            return null;
        }
    }
    
    // 解析 Transactional 注解属性
    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"));
    
        ListRollbackRuleAttribute 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;
    }
    

    在这里就可以看到,事务注解 @Transactional 的各种各样的属性了。

    当然,到这里还没有完;到这里,可以从下往上看下所有的代码,当方法存在 @Transactional注解的时候,该方法就会满足增强器 BeanFactoryTransactionAttributeSourceAdvisor ,之后就会为我们的目标 bean 创建代理,并把增强器   BeanFactoryTransactionAttributeSourceAdvisor 织入到代理中,进而来影响我们的业务逻辑。

    总结

    这篇文章主要介绍了 Spring 事务的初始化功能,在 Spring 加载的时候,会注册 InfrastructureAdvisorAutoProxyCreator bean,而该 bean 又实现了 BeanPostProcessor 接口,所以当目标 bean在初始化完成后,会执行 postProcessAfterInitialization 方法,在该方法中,会去遍历我们的目标 bean 中的方法,如果方法上有 @Transactional事务注解,则会为目标 bean 创建代理,并把 增强器   BeanFactoryTransactionAttributeSourceAdvisor 织入到代理中;当然, BeanFactoryTransactionAttributeSourceAdvisor  还拥有 AnnotationTransactionAttributeSource TransactionInterceptor 这两个 bean 会一起被织入代理。

    所以在 Spring事务初始化的过程中,主要注册了四个 bean

  • **`InfrastructureAdvisorAutoProxyCreator`**
  • **`BeanFactoryTransactionAttributeSourceAdvisor`**
  • **`AnnotationTransactionAttributeSource`**
  • **`TransactionInterceptor`**
  • BeanFactoryTransactionAttributeSourceAdvisor

    TransactionInterceptor

    InfrastructureAdvisorAutoProxyCreator 主要是用来查找方法,类或者接口上的事务注解   @Transactional,如果存在注解,则为目标 bean 创建代理,并把其他的三个 bean 织入到代理中,而另外的三个 bean 主要是用来 执行目标方法,进行事务的提交和回滚。

    BeanFactoryTransactionAttributeSourceAdvisor

    关于使用 BeanFactoryTransactionAttributeSourceAdvisor AnnotationTransactionAttributeSource TransactionInterceptor  来执行目标方法,提交事务,回滚事务,则在下一篇文章中分析。

    原文始发于微信公众号(Java技术大杂烩):

    本人花费半年的时间总结的《Java面试指南》已拿腾讯等大厂offer,已开源在github ,欢迎star!

    本文GitHub https://github.com/OUYANGSIHAI/JavaInterview 已收录,这是我花了6个月总结的一线大厂Java面试总结,本人已拿大厂offer,欢迎star

    原文链接:blog.ouyangsihai.cn >> Spring 事务初始化源码分析


     上一篇
    Spring 事务使用详解 Spring 事务使用详解
    前言什么是事务?根据 维基百科事务 介绍,数据库事务(简称:事务)是数据库管理系统执行过程中的一个逻辑单位,由一个有限的数据库操作序列构成。简单来说,事务就是将一系列操作当成一个不可拆分的执行逻辑单元,这些要么都成功,要么都失败。事务具有4
    2021-04-05
    下一篇 
    Spring 事务提交回滚源码解析 Spring 事务提交回滚源码解析
    前言在上篇文章   中分析了 Spring 事务初始化的一个过程,当初始化完成后,Spring 是如何去获取事务,当目标方法异常后,又是如何进行回滚的,又或是目标方法执行成功后,又是怎么提交的呢?此外,事务的提交和回滚由底层数据库进行控制,
    2021-04-05