美文网首页
Spring中@Transactional注解到底做了什么(四)

Spring中@Transactional注解到底做了什么(四)

作者: 夜流星_9775 | 来源:发表于2020-04-18 12:23 被阅读0次

    候选增强器中寻找到匹配项

    上次我们看到matches这个方法,今天走进getTransactionAttribute方法中看看

        @Override
        public boolean matches(Method method, Class<?> targetClass) {
            TransactionAttributeSource tas = getTransactionAttributeSource();
            return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
        }
    
    @Override
        @Nullable
        public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
            if (method.getDeclaringClass() == Object.class) {
                return null;
            }
    
            // First, see if we have a cached value.
            Object cacheKey = getCacheKey(method, targetClass);
            TransactionAttribute cached = this.attributeCache.get(cacheKey);
            if (cached != null) {
                  ...................
            }
            else {
                // We need to work it out.
                TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
                            ...................
            }
        }
    

    提取事务标签

    在这个方法中,我们只关注computeTransactionAttribute方法,在computeTransactionAttribute函数中我们终于看到了事务标签的提取过程。

    @Nullable
        protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
            // Don't allow no-public methods as required.
            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;
                }
            }
    
            return null;
        }
    

    这个方法做的事情就很清楚了,解析一个bean是否存在事务,首先在方法中查找是否存在事务,然后在类中查找是否存在事务。如果存在接口,则在接口中查找,然后依次按照方法和类进行事务的查找。
    跟着上面的findTransactionAttribute方法一直往下走,最后在AnnotationTransactionAttributeSource类中我们看到了这个方法parseTransactionAnnotation,很明显,准备解析事务的参数了

    @Nullable
        protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
            for (TransactionAnnotationParser parser : this.annotationParsers) {
                TransactionAttribute attr = parser.parseTransactionAnnotation(element);
                if (attr != null) {
                    return attr;
                }
            }
            return null;
        }
    

    看到下面这个方法,我们就了解了事务是怎么加载它自己的参数的了。

    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;
        }
    

    事务的标签属性加载完毕,至此,事务功能的初始化工作便结束了

    相关文章

      网友评论

          本文标题:Spring中@Transactional注解到底做了什么(四)

          本文链接:https://www.haomeiwen.com/subject/cfjvvhtx.html