栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring及Spring boot 第四章-第二节 Spring声明式事务管理 解析@Transactional

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring及Spring boot 第四章-第二节 Spring声明式事务管理 解析@Transactional

Spring及Spring boot 第四章-第二节 Spring声明式事务管理 解析@Transactional
        • (1) 获取Advisor——BeanFactoryTransactionAttributeSourceAdvisor
        • (2)判断Advisor是否应用于该Bean
          • AopUtils#canApply——非常重要的场景
          • 2.1 粗筛 ——判断Bean类中有没有@Transactional注解
          • 2.2 真正的筛选
            • TransactionAttributeSourcePointcut#matches ——这里有最重要的一步,拿到通过tas拿到我们的BeanDefinition
            • 根据TransactionAttributeSource拿到@Transactional包装的所有事务信息
        • 附录
          • 解析@Transactional转变过程
            • Advisor——Pointcut
            • Pointcut——MethodMatcher
            • MethodMatcher(Pointcut本身)—— TransactionAttributeSource

这个过程可以和@Aspect 实现的AOP来进行对比

SpringAop获取Advisor

(1) 获取Advisor——BeanFactoryTransactionAttributeSourceAdvisor

@Transactional和@Aspect获取Advisor的不同之处在于它的Advisor一开始便是以Bean的形式存在,不需要通过解析@Aspect注解来将方法转化为Advisor

(2)判断Advisor是否应用于该Bean

在Spring声明式事务管理解析@Transactional注解的过程中会将它的信息转化为TransactionAttribute对象,

首先进行判断,BeanFactoryTransactionAttributeSourceAdvisor不是IntroductionAdvisor类型然后开始判断canApply,这是重点

IntroductionAdvisor的意义是实现AOP引入功能,和切点功能还不太一样。这里BeanFactoryTransactionAttributeSourceAdvisor当然是作为PointCutAdvisor
参考链接跟着小马哥学系列之 Spring AOP

AopUtils#canApply——非常重要的场景

它做了两件事

1. 判断这个目标类上有没有@Transactional注解,这样就可以知道事务相关的Advisor(BeanFactoryTransactionAttributeSourceAdvisor)能不能应用于该Bean,方便做之后的处理
2.  如果有,之后就进行真正的@Transactional注解解析,这里是非常重要的点(获取TransactionDefinition)
 public static boolean canApply(Pointcut pc, Class targetClass, boolean hasIntroductions) {
        Assert.notNull(pc, "Pointcut must not be null");
        if (!pc.getClassFilter().matches(targetClass)) {
            return false;
        } else {
            MethodMatcher methodMatcher = pc.getMethodMatcher();
            if (methodMatcher == MethodMatcher.TRUE) {
                return true;
            } else {
                IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
                if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
                    introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher)methodMatcher;
                }

                Set> classes = new LinkedHashSet();
                if (!Proxy.isProxyClass(targetClass)) {
                    classes.add(ClassUtils.getUserClass(targetClass));
                }

                classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
                Iterator var6 = classes.iterator();

                while(var6.hasNext()) {
                    Class clazz = (Class)var6.next();
                    Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
                    Method[] var9 = methods;
                    int var10 = methods.length;

                    for(int var11 = 0; var11 < var10; ++var11) {
                        Method method = var9[var11];
                        if (introductionAwareMethodMatcher != null) {
                            if (introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) {
                                return true;
                            }
                        } else if (methodMatcher.matches(method, targetClass)) {
                            return true;
                        }
                    }
                }

                return false;
            }
        }
    }
2.1 粗筛 ——判断Bean类中有没有@Transactional注解

这步属于粗筛,一方面我们都知道@Transactional注解是可以加到方法或者类上的,粗筛会通过把这个类上的所有注解都遍历一下看有没有Transactional.Class类型的注解,只做这一件事,返回个true或者false,不属于真正对@Transactional的处理

TransactionAttributeSourceClassFilter#matches 

这里就需要通过TransactionAttributeSource的实现类(AnnotationTransactionAttributeSource)来实现

AnnotationTransactionAttributeSource#isCandidateClass(clazz)

2.2 真正的筛选

重点
methodMatcher.matches(method, targetClass)


从附录中可以看到实现的就是TransactionAttributeSourcePointcut#matches

TransactionAttributeSourcePointcut#matches ——这里有最重要的一步,拿到通过tas拿到我们的BeanDefinition

一定要对命名有敏感,TransactionAttributeSource就是TransactionAttribute源,也就是说,所有的TransactionAttribute保存到TransactionAttributeSource相关的实现类中,TransactionAttribute就是我们事务功能实现中的TransactionDefinition组件。

缓存


不出意外拿到@Transactional注解 事务信息的话,这里就会返回true,整个获得Advisor的过程就成功结束

根据TransactionAttributeSource拿到@Transactional包装的所有事务信息

这个过程可以是从AbstractFallbackTransactionAttributeSource#getTransactionAttribute开始的,可以跳转查看

Spring及Spring boot 第四章-第二节 Spring声明式事务管理 AbstractFallbackTransactionAttributeSource

附录 解析@Transactional转变过程 Advisor——Pointcut


Pointcut——MethodMatcher


TransactionAttributeSourcePointcut实现的是父类StaticMethodMatcherPointcut的getMethodMatcher

其实就是返回TransactionAttributeSourcePointcut对象自己。

MethodMatcher(Pointcut本身)—— TransactionAttributeSource

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1031882.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号