死磕Spring之AOP篇 - Spring 事务详解 (6)

可以看到,默认情况是只支持 public 修饰的方法,对于方法和类上面的 @Transactional 注解都是支持的,优先从方法上面解析,其次从所在类上面解析,处理过程都在 findTransactionAttribute(..) 方法中

3. findTransactionAttribute 方法 // AnnotationTransactionAttributeSource.java @Override protected TransactionAttribute findTransactionAttribute(Class<?> clazz) { // 解析类上面的 @Transactional 注解,并将注解的元信息封装到 RuleBasedTransactionAttribute 中 return determineTransactionAttribute(clazz); } @Override protected TransactionAttribute findTransactionAttribute(Method method) { // 解析方法上面的 @Transactional 注解,并将注解的元信息封装到 RuleBasedTransactionAttribute 中 return determineTransactionAttribute(method); } protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) { for (TransactionAnnotationParser annotationParser : this.annotationParsers) { // 通过 SpringTransactionAnnotationParser 解析 @Transactional 注解 TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element); if (attr != null) { return attr; } } return null; }

通过 SpringTransactionAnnotationParser 解析器进行方法或者类上面的 @Transactional 注解

4. SpringTransactionAnnotationParser public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable { @Override @Nullable public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) { // 找到这个方法的 @Transactional 注解 AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes( element, Transactional.class, false, false); if (attributes != null) { // 将 @Transactional 注解的元信息封装到 RuleBasedTransactionAttribute 对象中 return parseTransactionAnnotation(attributes); } else { return null; } } public TransactionAttribute parseTransactionAnnotation(Transactional ann) { return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false)); } 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<>(); // 设置接收到哪些 Class 对象(异常)需要回滚 for (Class<?> rbRule : attributes.getClassArray("rollbackFor")) { rollbackRules.add(new RollbackRuleAttribute(rbRule)); } for (String rbRule : attributes.getStringArray("rollbackForClassName")) { rollbackRules.add(new RollbackRuleAttribute(rbRule)); } // 设置接收到哪些 Class 对象(异常)不需要回滚 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 注解解析成 RuleBasedTransactionAttribute 对象(实现了 TransactionDefinition 接口),设置相关属性,不存在这个注解的话返回 null

小节

在这个 PointcutAdvisor 切面关联着一个 Pointcut 切点,为 TransactionAttributeSourcePointcut 对象,内部有一个 AnnotationTransactionAttributeSource 事务属性资源对象。在这个切点判断某个方法是否需要进行事务处理时,通过内部的 AnnotationTransactionAttributeSource 对象解析 @Transactional 注解(没有的话表示不匹配),解析过程需要借助于 SpringTransactionAnnotationParser 解析器解析 @Transactional 注解,将这个事务定义的一些属性封装成一个 RuleBasedTransactionAttribute 事务定义对象(实现了 TransactionDefinition 接口),并缓存

TransactionInterceptor 事务拦截处理

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zygsff.html