文章目录
目录
文章目录
前言
一、切入点以及切面的匹配规则
1.1 TransactionAttributeSourcePointcut事务的切入点匹配
二、TransactionInterceptor切面的具体逻辑
2.1 声明式事务实现的具体逻辑
总结
前言
上一篇文章已经说过了声明式事务的原理其实就是SpringAop动态增强,而动态将切面织入切入点的逻辑在AbstractAdvisorAutoProxyCreator中,事务和普通的AOP分别由InfrastructureAdvisorAutoProxyCreator和AnnotationAwareAspectJAutoProxyCreator去完成织入。而方法匹配到切面的逻辑,以及的增强逻辑,如事务的开启和提交,则在具体的Advisor和Pointcut中。想要详细的了解请看文章《Spring中申明式事务(@Transactional)实现的原理解析》
本篇文章则针对具体的Advisor和Pointcut进行申明式事务的具体增强逻辑的分析。
一、切入点以及切面的匹配规则
上篇文章说过@EnableTransactionManagement注解通过@Import引入了两个类AutoProxyRegistrar和ProxyTransactionManagementConfiguration。AutoProxyRegistrar则是InfrastructureAdvisorAutoProxyCreator来创建AOP的代理对象,而ProxyTransactionManagementConfiguration则是用来注入切入点和切面的
这里是向Spring容器中注入了BeanFactoryTransactionAttributeSourceAdvisor,同时向这个Advisor中注入了TransactionAttributeSource和TransactionInterceptor。
1.1 TransactionAttributeSourcePointcut事务的切入点匹配
顾名思义,这个类是一个Advisor,也就是切面类,里面配置了切入点匹配规则以及切面逻辑。看过上一篇文章应该会知道,在创建AOP的环节中需要查找所有切点中的符合Advisor类型的类。这个类正是事务的增强类。
这里面有一个切入点Pointcout,在这里的具体实现类为TransactionAttributeSourcePointcut,
结合上一篇文章 《Spring中申明式事务(@Transactional)实现的原理解析》,如果方法满足:
pointCout.getClassFilter().matches(targetClass)
返回truepointCout.getMethodMatcher().matches(method, targetClass)
返回true
则是该增强的一个切入点,就会织入切面逻辑。所以下面来看一下该Pointcut的匹配逻辑。
可以看到Pointcut中的ClassFilter#match方法最终是调用了TransactionAttributeSource#isCandidateClass方法,在上面的第一张截图中,ProxyTransactionManagementConfiguration中在Advisor中注入了AnnotationTransactionAttributeSource,所以需要看这个TransactionAttributeSource中的方法。进入的TransactionAttributeSourced#isCandidateClass方法
最终调用的还是TransactionAnnotationParser的isCandidateClass方法 。根据图一,TransactionAnnotationParser注入的具体实现类为AnnotationTransactionAttributeSource。进入该类查看具体的实现逻辑。
最终调用的是SpringTransactionAnnotationParser#isCandidateClass方法。
可以看出这里面是匹配了@Transactional注解,并且解析了注解里面的属性。
二、TransactionInterceptor切面的具体逻辑
2.1 声明式事务实现的具体逻辑
上面已经匹配到了植入点,接下来就是切面的具体逻辑了,而切面的具体逻辑就在TransactionInterceptor中。这里主要是invoke方法
主要得事务逻辑就在TransactionAspectSupport#invokeWithinTransaction方法中了。逻辑包括开启事务、执行方法、提交事务,有异常得时候回滚事务等
总结
事务和AOP其实是原理都是一样的,而事务的重点在于使用事务的时候需要注意事务的提交、回滚等,而声明式事务主要通过注解的属性或者一些默认配置来控制这些,我们只有理解了声明式事务的原理,才能更好更安全的去使用,后面会再针对声明式事务使用的时候需要注意的问题展开讨论,比如:事务失效、事务传播特性等