前言
看到这篇文章的标题,是不是觉得模棱两可,莫名其妙。其实,我也觉得这个标题很烂,但是我实在没有想好该怎么描述这件事。
还是从一个问题开始:
如果一个service中父类的方法加了 @Transactional
注解,那么子类中重写该父类方法的那个方法是否会开启事务?
貌似问题还是有点绕,用大白话再解释一下,父类中有方法 a(), 方法a()上加了事务的注解,子类重写了方法a(),那么子类中的方法a()会开启事务吗?
废话有点多,先说答案:会。
分析
刚开始遇到这个问题的时候,思考的方向不对,一直在注解的继承性上下文章,结果在网上查了很多资料,大家的答案都是:如果子类重写了父类的方法,那么子类将不会继承父类的注解。
但是。。。我实际的测试中,子类重写了父类的方法,调用子类中的方法,确实也开启了事务。
源码
在网上找不到结果,就只有在源码中找寻答案了。
首先,springboot中是不用在启动类中加注解@EnableTransactionManagement
来开启注解事务的。原因可以看springboot的自动配置类TransactionAutoConfiguration
我们的故事也会从 @EnableTransactionManagement 开始:
EnableTransactionManagement
@Import(TransactionManagementConfigurationSelector.class)注解;
TransactionManagementConfigurationSelector
import AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration , 我们主要追踪 ProxyTransactionManagementConfiguration 。
ProxyTransactionManagementConfiguration
有三个类注入:BeanFactoryTransactionAttributeSourceAdvisor、TransactionAttributeSource、TransactionInterceptor。
TransactionInterceptor
invoke()
TransactionAspectSupport
invokeWithinTransaction()
关注这段注释 // If the transaction attribute is null, the method is non-transactional.
AbstractFallbackTransactionAttributeSource
getTransactionAttribute()
computeTransactionAttribute(method, targetClass)
AnnotationTransactionAttributeSource
findTransactionAttribute()
determineTransactionAttribute()
SpringTransactionAnnotationParser
parseTransactionAnnotation()
AnnotatedElementUtils
findMergedAnnotationAttributes()
searchWithFindSemantics()
searchWithFindSemantics()
searchWithFindSemantics(), 这个方法很长,但是我们可以从这个方法中发现,如果element是method,则会查找父类的注解。
总结
这篇文章的排版有点独特,因为我也不知道怎么合适的表达一个长流程的调用关系,在我找到一个合适且清晰的方法之前,我可能会一直使用这种方法。
这篇文章主要为了跟踪spring查找事务注解的流程。