声明式事务工作原理
@EnableTransactionManagement
注解会给容器中导入TransactionManagementConfigurationSelector
组件
@EnableTransactionManagement
注解的AdviceMode
默认值为Proxy
TransactionManagementConfigurationSelector
组件会调用selectImports()
方法带导入AutoProxyRegistrar
和ProxyTransactionManagementConfiguration
这两个组件
AutoProxyRegistrar
组件给容器中注册Bean
AutoProxyRegistrar
实现了ImportBeanDefinitionRegistrar
接口,会调用registerBeanDefinitions()
方法给容器中注册Bean
判断mode==AdviceMode.Proxy
,然后调用AopConfigUtils
的registerAutoProxyCreatorIfNecessary()
方法,进而调用registerOrEscalateApcAsRequired()
方法,给容器中注册一个InfrastructureAdvisorAutoProxyCreator
组件,这个组件也是一个后置处理器
InfrastructureAdvisorAutoProxyCreator
组件利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行
ProxyTransactionManagementConfiguration
组件给容器中注册事务增强器
ProxyTransactionManagementConfiguration
是一个配置类,给容器中注册事务增强器
AnnotationTransactionAttributeSource()
方法会解析事务注解
SpringTransactionAnnotationParser
中parseTransactionAnnotation()
方法进行解析注解
除了解析事务注解信息,还要执行事务拦截器TransactionInterceptor
,事务拦截器保存了事务属性信息,还保存了事务管理器
TransactionInterceptor
实现了MethodInterceptor
接口,容器中代理对象执行目标方法时,方法拦截器来链就会执行
invokeWithinTransaction()
方法利用事务进行工作,现获取TransactionAttribute
事务相关的属性,再获取PlatformTransactionManager
平台事务管理器
determineTransactionManager()
方法来获取事务管理器,如果有指定的就获取指定的事务管理器,如果没有指定,就会从容器中获取注册的事务管理器
invocation.proceedWithInvocation()
执行事务方法,与之前MethodInvocation
执行机制一样
completeTransactionAfterThrowing()
处理异常的方法会获取事务管理器,进行回滚
如果没有异常,获取事务管理器提交事务
总结
-
@EnableTransactionManagement
注解会给容器中导入AutoProxyRegistrar
和ProxyTransactionManagementConfiguration
两个组件 -
AutoProxyRegistrar
组件:
(1)这个组件会给容器中注册一个InfrastructureAdvisorAutoProxyCreator
组件
(2)InfrastructureAdvisorAutoProxyCreator
组件是一个后置处理器
(3)InfrastructureAdvisorAutoProxyCreator
利用后置处理器机制在对象创建以后,包装对象并返回一个代理对象,代理对象执行目标方法时,利用拦截器链进行增强处理 -
ProxyTransactionManagementConfiguration
组件:
(1)这个组件用来给容器中注册事务增强器
(2)事务增强器需要用到事务注解信息,使用AnnotationTransactionAttributeSource
解析事务注解
(3)事务拦截器TransactionInterceptor
事务拦截器实现了MethodInvocation
接口,用来保存事务属性信息,保存事务管理器
(4)代理对象执行目标方法时,会执行事务拦截器链
(5)链中每一个事务拦截器都是:先获取事务相关的属性;再获取PlatformTransactionManager
平台事务管理器,如果没有指定任何的事务管理器,就会从容器中按照类型获取一个事务管理器;最后执行目标方法,如果出现异常,则会获取到事务管理器,利用事务管理器进行回滚操作,如果没有出现异常,则会获取事务管理器,利用事务管理器提交事务。