上回说到,使用事务的模板TransactionTemplate
可以极大地减少我们使用事务时的工作,我们只需将我们的业务逻辑写到TransactionCallback
接口方法中即可。
使用TransactionTemplate
虽然帮我们省略了一些相同的操作,但是每次数据库操作都要写到TransactionCallback
中,也业务逻辑还不是分离的。这就引出了AOP代理。
要将Spring AOP和事务结合起来,也有很多的表现形式,但原理都是一样的。
最简单的莫过于在Configuration类中增加@EnableTransactionManagement
,Spring将标注有@Transactional
的对象创建出代理对象。
生成beanDefinition
在Configuration类中增加了@EnableTransactionManagement
,Spring启动时在解析Configuration时
调用invokeBeanFactoryPostProcessors
生成beanDefinition
invokeBeanFactoryPostProcessors
->PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors
->invokeBeanDefinitionRegistryPostProcessors
->ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry(registry)
->processConfigBeanDefinitions(registry)
->ConfigurationClassParser.parse(candidates)
->processConfigurationClass(configClass)
->doProcessConfigurationClass(configClass, sourceClass)
invokeBeanDefinitionRegistryPostProcessors
在处理Import注释时,我们知道@EnableTransactionManagement
中加了注释@Import(TransactionManagementConfigurationSelector.class)
,因此会调用ConfigurationClassParser.processImports
。
1 | private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, |
importCandidates里传入的是TransactionManagementConfigurationSelector
。
可以看到,因为传入的TransactionManagementConfigurationSelector
是ImportSelector
的子类,于是首先调用AdviceModeImportSelector.selectImports
获取需要导入的类,能看到是org.springframework.context.annotation.AutoProxyRegistrar
和org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration
。然后递归调用processImports
。
接着看AutoProxyRegistrar
,它是ImportBeanDefinitionRegistrar
的子类。调用ParserStrategyUtils.invokeAwareMethods
执行实现的Aware
接口。然后调用configClass.addImportBeanDefinitionRegistrar
在config类中增加importBeanDefinitionRegistrar。
接着看ProxyTransactionManagementConfiguration
,它既不是ImportSelector
类也不是ImportBeanDefinitionRegistrar
类,于是进入else代码块,调用processConfigurationClass
,将它作为一个配置类来处理。
查看ProxyTransactionManagementConfiguration
类的代码,我们可以看到ProxyTransactionManagementConfiguration
被@Configuraion
注释,它还新建了3个bean:BeanFactoryTransactionAttributeSourceAdvisor
、TransactionAttributeSource
、TransactionInterceptor
。
loadBeanDefinitions
回到ConfigurationClassPostProcessor.processConfigBeanDefinitions
方法,经过parser.parse
的解析,configClasses中包含了我们自定义的Configuration类以及ProxyTransactionManagementConfiguration
,还包含通过ComponentScan扫描得到的类。
调用ConfigurationClassBeanDefinitionReader.loadBeanDefinitions
:
- 加载自定义Configuration类中定义bean的beanDefinition。之前在importBeanDefinitionRegistrar中添加了
AutoProxyRegistrar
,因此调用registerBeanDefinitions
方法注册了InfrastructureAdvisorAutoProxyCreator
- 加载
ProxyTransactionManagementConfiguration
以及其中四个bean(BeanFactoryTransactionAttributeSourceAdvisor
、TransactionAttributeSource
、TransactionInterceptor
、TransactionalEventListenerFactory
)的beanDefinition。
invokeBeanFactoryPostProcessors
调用ConfigurationClassPostProcessor.postProcessBeanFactory
:
- 使用cglib对Configuration类进行增强
- 增加一个
ImportAwareBeanPostProcessor
注册beanPostProcessors
在调用registerBeanPostProcessors
之前,beanFactory
的beanPostProcessors
中有三个beanPostProcessor:
- ApplicationContextAwareProcessor
- ApplicationListenerDetector
- ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
在调用invokeBeanFacotryPostProcessors
之后,调用registerBeanPostProcessors
注册beanPostProcessor
。注册完之后beanFactory
的beanPostProcessors
中有8个beanPostProcessor:
- ApplicationContextAwareProcessor
- ConfigurationClassPostProcessor$ImportAwareBeanPostProcessor
- PostProcessorRegistrationDelegate$BeanPostProcessorChecker
- InfrastructureAdvisorAutoProxyCreator
- CommonAnnotationBeanPostProcessor
- AutowiredAnnotationBeanPostProcessor
- RequiredAnnotationBeanPostProcessor
- ApplicationListenerDetector
创建bean并初始化
与AOP代理类相同,bean创建工作在DefaultListableBeanFactory.doCreateBean
中完成:
- 调用
AbstractAutowireCapableBeanFactory.createBeanInstance
创建bean实例。 - 调用
AbstractAutowireCapableBeanFactory.populateBean
填充bean实例。 - 调用
AbstractAutowireCapableBeanFactory.initializeBean
初始化bean实例
在initializeBean
方法中,调用applyBeanPostProcessorsAfterInitialization
,它调用各个beanPostProcessor的postProcessAfterInitialization
。
重点是InfrastructureAdvisorAutoProxyCreator
,它创建了使用事务的类的代理类。
AbstractAutoProxyCreator.postProcessAfterInitialization
->AbstractAutoProxyCreator.wrapIfNecessary
->
在AbstractAutoProxyCreator.wrapIfNecessary
方法中:
1 | Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null); |
寻找拦截器
Spring通过调用AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean
方法来获取某个bean的所有advice。它实际调用的是AbstractAdvisorAutoProxyCreator.findEligibleAdvisors
方法,为这个类寻找合适的advice。主要流程如下:
- 调用
AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()
方法寻找所有的advisor。其中会在Spring容器里寻找名称为org.springframework.transaction.config.internalTransactionAdvisor
的bean对象,返回的是一个BeanFactoryTransactionAttributeSourseAdvisor
类对象,它用于在一个使用事务的方法中加入事务通知。 调用
AbstractAdvisorAutoProxyCreator.findAdvisorsThatCanApply()
方法在所有advisor中筛选适合这个类对象的advisor。它实际调用的是
AopUtils.canApply
方法来确定advisor的pointcut是否能匹配这个类对象,原理如下:- 调用Pointcut的
getMethodMatcher
方法获取MethodMatcher
对象。该对象是Pointcut的一部分,用于判断目标方法是否匹配advice。 - 获取目标对象的所有的方法,然后遍历这些方法,调用
BeanFactoryTransactionAttributeSourseAdvisor
父类TransactionAttributeSourcePointcut
的matches
方法来判断目标方法是否匹配Pointcut。其原理是通过是否能在目标方法的注释中找到事务属性(TransactionAttribute)来判断是否匹配Pointcut。
- 调用Pointcut的
创建代理类
通过getAdvicesAndAdvisorsForBean
方法找到一个拦截器BeanFactoryTransactionAttributeSourceAdvisor
。因此需要创建一个代理类:
- 调用
DefaultAopProxyFactory.createAopProxy
来创建一个AopProxy - 调用
CglibAopProxy.getProxy
来获取一个代理类
代理类中加入了DynamicAdvisedInterceptor
、StaticUnadvisedInterceptor
、SerializableNoOp
、StaticDispatcher
、AdvisedDispatcher
、EqualsInterceptor
、HashCodeInterceptor
等一系列的拦截器。
执行@Transactional注释的方法
当调用@Transactional注释的方法时,调用的是DynamicAdvisedInterceptor.intercept
。
首先执行AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass)
获取拦截器列表。调用流程如下:
- DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice
- DefaultAdvisorAdapterRegistry.getInterceptors方法返回TransactionInterceptor
获取到的拦截器链中有TransactionInterceptor
。
接着新建CglibMethodInvocation
对象,执行ReflectiveMethodInvocation.proceed
方法
1 | public Object proceed() throws Throwable { |
其中interceptorOrInterceptionAdvice
中获得的拦截器是TransactionInterceptor
,然后执行到((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this)
语句,进入TransactionInterceptor.invoke
,然后进入TransactionAspectSupport.invokeWithinTransaction
。
1 | ... |
调用createTransactionIfNecessary
创建事务:
1 | protected TransactionInfo createTransactionIfNecessary( |
调用tm.getTransaction
获取事务状态,具体可以参考Spring与事务(一)。
接着调用prepareTransactionInfo
封装一个事务信息的对象。
回到TransactionAspectSupport.invokeWithinTransaction
方法,调用createTransactionIfNecessary
根据需要创建一个事务之后,再调用回调函数:invocation.proceedWithInvocation
调用用户代码,进入ReflectiveMethodInvocation.proceed
,:
1 | public Object proceed() throws Throwable { |
调用invokeJoinPoint
执行用户的业务代码:
1 | protected Object invokeJoinpoint() throws Throwable { |
回到TransactionAspectSupport.invokeWithinTransaction
方法。如果invocation.proceedWithInvocation
执行成功,则调用commitTransactionAfterReturning
提交事务;否则调用completeTransactionAfterThrowing
回滚事务。