在上一篇文章@EnableTransactionManagement注解解析中,我们搭建了源码阅读的环境,以及解析了开启Spring事务功能的注解@EnableTransactionManagement
的实现逻辑
在进行接下来的源码解析之前我想大家应该知道,当我们使用传统的jdbc应用事务的时候是不是做了如下操作:
开启事务
save、update、delete等操作
出现异常进行回滚
正常情况提交事务
而在Spring中我们好像只需要关心第三步,也就是我们的业务,而其他的操作都不需要关心。那么我想你应该猜到了Spring是如何实现的呢?
答案就是基于@Transactional
注解的SpringAOP实现,在接着往下阅读本篇文章的时候希望您对于SpringAOP的源码有一定的了解,如果不了解可以参考如下文章:
基于注解的SpringAOP源码解析(一)
基于注解的SpringAOP源码解析(二)
基于注解的SpringAOP源码解析(三)
获取增强
在阅读完AOP的原理之后,我们知道,当一个bean实例化之后会尝试获取所有适用于此Bean的增强。而在上篇文章中,我们已经发现了,@EnableTransactionManagement
注解会往Spring中注入一个增强BeanFactoryTransactionAttributeSourceAdvisor
。经过一番代码调用以后,会进入这么一个方法,这里的第一个入参就是BeanFactoryTransactionAttributeSourceAdvisor
增强
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| 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 pca = (PointcutAdvisor) advisor; return canApply(pca.getPointcut(), targetClass, hasIntroductions); } else { return true; } } 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; } MethodMatcher methodMatcher = pc.getMethodMatcher(); if (methodMatcher == MethodMatcher.TRUE) { return true; }
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null; if (methodMatcher instanceof IntroductionAwareMethodMatcher) { introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher; }
Set<Class<?>> classes = new LinkedHashSet<>(ClassUtils.getAllInterfacesForClassAsSet(targetClass)); classes.add(targetClass); 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; }
|
到这里的时候就进入事务相关的类TransactionAttributeSourcePointcut
,看名字就能知道,这是个切点类.那么接下来的逻辑应该可以想象到,无非就是判断是否是个事务方法
1 2 3 4 5 6 7
| public boolean matches(Method method, @Nullable Class<?> targetClass)
TransactionAttributeSource tas = getTransactionAttributeSource(); return (tas == null || tas.getTransactionAttribute(method, targetClass) != null); }
|
如果是事务方法则继续往下走
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) { if (method.getDeclaringClass() == Object.class) { return null; }
Object cacheKey = getCacheKey(method, targetClass); Object cached = this.attributeCache.get(cacheKey); if (cached != null) { if (cached == NULL_TRANSACTION_ATTRIBUTE) { return null; } else { return (TransactionAttribute) cached; } } else { TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass); 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); } this.attributeCache.put(cacheKey, txAttr); } return txAttr; } }
|
接着看一下方法的事务属性是如何解析的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
| protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass)
Class<?> userClass = (targetClass != null ? ClassUtils.getUserClass(targetClass) : null); Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass); specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod); TransactionAttribute txAttr = findTransactionAttribute(specificMethod); if (txAttr != null)
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass()); if (txAttr != null && ClassUtils.isUserLevelMethod(method))
// 如果通过解析到的方法无法找到事务属性,则判断解析得到的方法与传入的目标方法是否为同一个方法, // 如果不是同一个方法,则尝试对传入的方法及其所在的类进行事务属性解析 if (specificMethod != method)
// 对传入方法所在类进行事务属性解析,如果存在,则直接返回 txAttr = findTransactionAttribute(method.getDeclaringClass()); if (txAttr != null && ClassUtils.isUserLevelMethod(method))
}
return null; }
|
这里对事务属性的解析主要分为对目标方法进行解析和对传入方法进行解析,接着看findTransactionAttribute
方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77
| protected TransactionAttribute findTransactionAttribute(Method method) { return determineTransactionAttribute(method); } protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) { for (TransactionAnnotationParser annotationParser : this.annotationParsers) { TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae); if (attr != null) { return attr; } } return null; } public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes( ae, Transactional.class, false, false); if (attributes != null) { return parseTransactionAnnotation(attributes); } else { return null; } } public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) { AnnotationAttributes attributes = AnnotatedElementUtils .findMergedAnnotationAttributes(ae, Transactional.class, false, false); if (attributes != null) { return parseTransactionAnnotation(attributes); } else { 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")); ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<>(); Class<?>[] rbf = attributes.getClassArray("rollbackFor"); for (Class<?> rbRule : rbf) { RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule); rollBackRules.add(rule); } String[] rbfc = attributes.getStringArray("rollbackForClassName"); for (String rbRule : rbfc) { RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule); rollBackRules.add(rule); } Class<?>[] nrbf = attributes.getClassArray("noRollbackFor"); for (Class<?> rbRule : nrbf) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule); rollBackRules.add(rule); } String[] nrbfc = attributes.getStringArray("noRollbackForClassName"); for (String rbRule : nrbfc) { NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule); rollBackRules.add(rule); } rbta.getRollbackRules().addAll(rollBackRules); return rbta; }
|
可以看到这里已经把方法上或者类上的@Transactional
注解的属性封装成TransactionAttribute
返回了,关于@Transactional
注解的更多知识可参考我的这篇文章:
Spring@Transactional注解