参考资料
- 视频 - 声明式事务-源码分析
源码分析
声明式事务所使用的注解 @EnableTransactionManagement
和之前分析过的 AOP 功能所使用的注解 @EnableAspectJAutoProxy
功能相似,可以参考之前的流程进行分析。
1、注解驱动 @EnableTransactionManagement
查看源码:
利用 TransactionManagementConfigurationSelector
给容器中会导入组件。
adviceMode
默认值为 AdviceMode.PROXY
,因此 TransactionManagementConfigurationSelector
会导入两个组件:
AutoProxyRegistrar
ProxyTransactionManagementConfiguration
下面来分析两个组件完成的功能。
2、AutoProxyRegistrar
AutoProxyRegistrar#registerBeanDefinitions()
注解 @EnableTransactionManagement
中 proxyTargetClass()
默认为 false
。
因此调用的是 AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
该方法给容器中注册了组件 InfrastructureAdvisorAutoProxyCreator
。
该组件类似于 AOP 中的 AnnotationAwareAspectJAutoProxyCreator
,也是一个后置处理器。
2.1、后置处理器 InfrastructureAdvisorAutoProxyCreator
继承关系图:
参考AOP原理,InfrastructureAdvisorAutoProxyCreator
利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行调用。
3、ProxyTransactionManagementConfiguration
ProxyTransactionManagementConfiguration
给容器中注册事务增强器 AnnotationTransactionAttributeSource
。
ProxyTransactionManagementConfiguration#transactionAttributeSource()
3.1、解析事务注解 AnnotationTransactionAttributeSource
事务增强器要用事务注解的信息,AnnotationTransactionAttributeSource
解析事务注解。
AnnotationTransactionAttributeSource#AnnotationTransactionAttributeSource()
SpringTransactionAnnotationParser#parseTransactionAnnotation()
除了事务注解信息,还注册了事务拦截器 TransactionInterceptor
。
3.2、事务拦截器 TransactionInterceptor
ProxyTransactionManagementConfiguration#transactionInterceptor
保存了事务属性信息 transactionAttributeSource
,事务管理器 txManager
。
继承关系图:
TransactionInterceptor
实现了 MethodInterceptor
,它是一个方法拦截器。
TransactionInterceptor#invoke()
在目标方法执行的时候,执行拦截器链,该拦截器链只有一个事务拦截器 TransactionInterceptor
。
TransactionAspectSupport#invokeWithinTransaction()
3.2.1、获取事务相关属性
3.2.2、获取 PlatformTransactionManager
如果事先没有添加指定任何 TransactionManager
,最终会从容器中按照类型获取一个 PlatformTransactionManager
。
TransactionAspectSupport#determineTransactionManager()
3.2.3、执行目标方法
如果异常,获取到事务管理器,利用事务管理回滚操作。
TransactionAspectSupport#completeTransactionAfterThrowing()
如果正常,利用事务管理器,提交事务。
TransactionAspectSupport#commitTransactionAfterReturning()