前言
在上一章我们分析了Spring的AOP的源码,本篇文章是对事务的源码分析,我们都知道事务的管理是基于AOP实现的,所以有了上一篇的铺垫这一章会比较简单一点。
事务的源码我会分两章写,一张写Transcational的解析,一张写事务的执行流程。先上一个图,待会儿可以根据这个图来看源码
事务配置案例
配置事务管理器,开启注解事务支持
< tx: annotation-driven/>
< bean id = " transactionManager" class = " org.springframework.jdbc.datasource.DataSourceTransactionManager" >
< property name = " dataSource" ref = " dataSource" />
</ bean>
< bean id = " dataSource" class = " com.alibaba.druid.pool.DruidDataSource" init-method = " init" destroy-method = " close" >
...省略...
</ bean>
标记方法需要事务
public class UserService . . . {
@Transactional
public void insert ( User user) {
. . .
}
}
事务注解打在方法上,当然也是可以打在类上。
事务注解原理
在Spring中通常有两种方式管理事务,一是使用XML统一配置事务 ,二是通过注解式编程即在对象方法上贴@Trancactional来管理事务,现在用的多的就是注解式编程,所以我们就从这个事务注解开始分析把。
Transactional贴在对象的方法上就可以通过AOP的方式帮我们开启事务,提交事务或是回滚事务操作,不仅简化了我们的工作难度,避免重复事务逻辑处理,同时也减少了代码的侵入,达到代码解耦和的效果。 事务的管理是基于AOP实现,AOP的原理又是动态代理,也就是说被标记了@Transactional的类都会创建代理类来实现事务增强,创建代理后,方法的真实调用都是走代理对象。那么Spring如何知道要对哪些类哪些方法进行代理?Spring会把 @Transactional 注解作为切点,这样就知道哪些方法需要被代理 。至于代理类的创建是在Bean的实例化过程中完成,在上一篇文章有说道,见:《AOP原理 》
事务标签解析器
NamespaceHandlerSupport 注册解析器
因为注解事务支持需要在XML中开启 ,所以对于事务来说可以分为两部分 :一是事务配置解析 ,二是代理创建。在上一章节我们就有提到,对于xml中的所有namespace都有对应的解析器, 在Spring中有一个接口叫 NamespaceHandlerSupport ,它提供了Spring xml配置的namespace的解析支持。 NamespaceHandlerSupport
它有一个子类 TxNaespaceHadler
就是针对于事务的 namespace 处理
public class TxNamespaceHandler extends NamespaceHandlerSupport {
static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager" ;
static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager" ;
static String getTransactionManagerName ( Element element) {
return ( element. hasAttribute ( TRANSACTION_MANAGER_ATTRIBUTE) ?
element. getAttribute ( TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME) ;
}
@Override
public void init ( ) {
registerBeanDefinitionParser ( "advice" , new TxAdviceBeanDefinitionParser ( ) ) ;
registerBeanDefinitionParser ( "annotation-driven" , new AnnotationDrivenBeanDefinitionParser ( ) ) ;
registerBeanDefinitionParser ( "jta-transaction-manager" , new JtaTransactionManagerBeanDefinitionParser ( ) ) ;
}
}
AnnotationDrivenBeanDefinitionParser创建AutoProxyCreator
看得出来上面的 init 方法中注册了一个 AnnotationDrivenBeanDefinitionParser
它就是针对于 <tx:annotation-driven/>
的解析器,并且负责创建事务管理需要的基础类。
class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
AnnotationDrivenBeanDefinitionParser ( ) {
}
public BeanDefinition parse ( Element element, ParserContext parserContext) {
this . registerTransactionalEventListenerFactory ( parserContext) ;
String mode = element. getAttribute ( "mode" ) ;
if ( "aspectj" . equals ( mode) ) {
this . registerTransactionAspect ( element, parserContext) ;
} else {
AnnotationDrivenBeanDefinitionParser. AopAutoProxyConfigurer. configureAutoProxyCreator ( element, parserContext) ;
}
return null;
}
AopAutoProxyConfigurer 创建事务核心类
这个parse解析方法注册了事务监听器后就判断了mode,默认使用的是proxy代理方式,即调用configureAutoProxyCreator
方法,一路跟下去
private static class AopAutoProxyConfigurer {
public static void configureAutoProxyCreator ( Element element, ParserContext parserContext) {
AopNamespaceUtils. registerAutoProxyCreatorIfNecessary ( parserContext, element) ;
String txAdvisorBeanName = TransactionManagementConfigUtils. TRANSACTION_ADVISOR_BEAN_NAME;
if ( ! parserContext. getRegistry ( ) . containsBeanDefinition ( txAdvisorBeanName) ) {
Object eleSource = parserContext. extractSource ( element) ;
RootBeanDefinition sourceDef = new RootBeanDefinition (
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource" ) ;
sourceDef. setSource ( eleSource) ;
sourceDef. setRole ( BeanDefinition. ROLE_INFRASTRUCTURE) ;
String sourceName = parserContext. getReaderContext ( ) . registerWithGeneratedName ( sourceDef) ;
RootBeanDefinition interceptorDef = new RootBeanDefinition ( TransactionInterceptor. class ) ;
interceptorDef. setSource ( eleSource) ;
interceptorDef. setRole ( BeanDefinition. ROLE_INFRASTRUCTURE) ;
registerTransactionManager ( element, interceptorDef) ;
interceptorDef. getPropertyValues ( ) . add ( "transactionAttributeSource" , new RuntimeBeanReference ( sourceName) ) ;
String interceptorName = parserContext. getReaderContext ( ) . registerWithGeneratedName ( interceptorDef) ;
RootBeanDefinition advisorDef = new RootBeanDefinition ( BeanFactoryTransactionAttributeSourceAdvisor. class ) ;
advisorDef. setSource ( eleSource) ;
advisorDef. setRole ( BeanDefinition. ROLE_INFRASTRUCTURE) ;
advisorDef. getPropertyValues ( ) . add ( "transactionAttributeSource" , new RuntimeBeanReference ( sourceName) ) ;
advisorDef. getPropertyValues ( ) . add ( "adviceBeanName" , interceptorName) ;
if ( element. hasAttribute ( "order" ) ) {
advisorDef. getPropertyValues ( ) . add ( "order" , element. getAttribute ( "order" ) ) ;
}
parserContext. getRegistry ( ) . registerBeanDefinition ( txAdvisorBeanName, advisorDef) ;
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition ( element. getTagName ( ) , eleSource) ;
compositeDef. addNestedComponent ( new BeanComponentDefinition ( sourceDef, sourceName) ) ;
compositeDef. addNestedComponent ( new BeanComponentDefinition ( interceptorDef, interceptorName) ) ;
compositeDef. addNestedComponent ( new BeanComponentDefinition ( advisorDef, txAdvisorBeanName) ) ;
parserContext. registerComponent ( compositeDef) ;
}
}
}
该方法先是创建了一个 InfrastructureAdvisorAutoProxyCreator
代理创建器 ,然后又注册了 AnnotationTransactionAttributeSource
, TransactionInterceptor
,BeanFactoryTransactionAttributeSourceAdvisor
三个Bean , 且前两个Bean被添加到了 BeanFactoryTransactionAttributeSourceAdvisor
中。
InfrastructureAdvisorAutoProxyCreator:是BeanPostProcessor的子类,在Bean的初始化之后调用postProcessAfterInitialization方法,目的就是找出增强器为合适的类创建代理。跟上一章节《AOP原理》做的事情差不多
AnnotationTransactionAttributeSource : 是专门用于获取基于注解的Spring声明式事务管理的事务属性的属性源,用来读取@Transational注解并进行相关参数封装,用做后续的事务处理。
它除了能处理Transactional注解之外,还支持JTA 1.2的javax.transaction.Transactional事务注解以及EJB3的javax.ejb.TransactionAttribute事务注解
TransactionInterceptor:该类实现了TransactionAspectSupport , TransactionAspectSupport 中持有 TransactionManager ,拥有处理事务的能力。同时该类还实现了 MethodInterceptor 接口 ,它也作为AOP的拦截器。拦截器链中每个拦截器都有一个invoke方法,该方法就是对某个方法进行事务增强的入口,因此主要看invoke方法的实现逻辑!
BeanFactoryTransactionAttributeSourceAdvisor:它是一个Advisor,用来对事务方法做增强,只要被注解@Transationl的方法都会被增强,该Advisor 包含 AnnotationTransactionAttributeSource 和 TransactionInterceptor ,以及 TransactionAttributeSourcePointcut 。
TransactionAttributeSourcePointcut 是事务属性源匹配器,是BeanFactoryTransactionAttributeSourceAdvisor的切入点,通过它来判断某个bean是否可以被增强
解析当前方法是否要被代理
InfrastructureAdvisorAutoProxyCreator
是一个BeanPostProcessor,当Bean在实例化过程中,会通过AutoProxyCreator的postProcessAfterInitialization
方法来决定是否创建代理,其实就是通过BeanFactoryTransactionAttributeSourceAdvisor
来解析判断该类是否被注解了@Transcational来决定是否创建代理 ,见:AbstractAutoProxyCreator#wrapIfNecessary
protected Object wrapIfNecessary ( Object bean, String beanName, Object cacheKey) {
if ( StringUtils. hasLength ( beanName) && this . targetSourcedBeans. contains ( beanName) ) {
return bean;
} else if ( Boolean. FALSE. equals ( this . advisedBeans. get ( cacheKey) ) ) {
return bean;
} else if ( ! this . isInfrastructureClass ( bean. getClass ( ) ) && ! this . shouldSkip ( bean. getClass ( ) , beanName) ) {
Object[ ] specificInterceptors = this . getAdvicesAndAdvisorsForBean ( bean. getClass ( ) , beanName, ( TargetSource) null) ;
if ( specificInterceptors != DO_NOT_PROXY) {
this . advisedBeans. put ( cacheKey, Boolean. TRUE) ;
Object proxy = this . createProxy ( bean. getClass ( ) , beanName, specificInterceptors, new SingletonTargetSource ( bean) ) ;
this . proxyTypes. put ( cacheKey, proxy. getClass ( ) ) ;
return proxy;
} else {
this . advisedBeans. put ( cacheKey, Boolean. FALSE) ;
return bean;
}
} else {
this . advisedBeans. put ( cacheKey, Boolean. FALSE) ;
return bean;
}
}
AbstractAdvisorAutoProxyCreator查找增强器
通过调用 AbstractAdvisorAutoProxyCreator#findCandidateAdvisors ,查找增强器 ,通过AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply 来匹配当前类适合的增强器,然后为当前Bean创建代理。这个流程在上一章: 《AOP原理 》 已经说过,这里就不细细分析了。见:AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
protected List< Advisor> findEligibleAdvisors ( Class< ? > beanClass, String beanName) {
List< Advisor> candidateAdvisors = this . findCandidateAdvisors ( ) ;
List< Advisor> eligibleAdvisors = this . findAdvisorsThatCanApply ( candidateAdvisors, beanClass, beanName) ;
this . extendAdvisors ( eligibleAdvisors) ;
if ( ! eligibleAdvisors. isEmpty ( ) ) {
eligibleAdvisors = this . sortAdvisors ( eligibleAdvisors) ;
}
return eligibleAdvisors;
}
我们重点来看一下它是如何匹配适合当前Bean的增强器的。见: AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply
protected List< Advisor> findAdvisorsThatCanApply (
List< Advisor> candidateAdvisors, Class< ? > beanClass, String beanName) {
ProxyCreationContext. setCurrentProxiedBeanName ( beanName) ;
try {
return AopUtils. findAdvisorsThatCanApply ( candidateAdvisors, beanClass) ;
}
finally {
ProxyCreationContext. setCurrentProxiedBeanName ( null) ;
}
}
这里的 candidateAdvisors 就是获取到的增强器 ,其中就包括:BeanFactoryTransactionAttributeSourceAdvisor , beanClass是当前要被创建代理的类,然后走的是AopUtils.findAdvisorsThatCanApply 方法查找能匹配当前类的advisors.一路断点跟下去会走到 AopUtils#canApply
public static boolean canApply ( Advisor advisor, Class< ? > targetClass, boolean hasIntroductions) {
if ( advisor instanceof IntroductionAdvisor ) {
return ( ( IntroductionAdvisor) advisor) . getClassFilter ( ) . matches ( targetClass) ;
}
else if ( advisor instanceof PointcutAdvisor ) {
PointcutAdvisor pca = ( PointcutAdvisor) advisor;
return canApply ( pca. getPointcut ( ) , targetClass, hasIntroductions) ;
}
else {
return true ;
}
}
AopUtils 查找合适的增强器
继续跟踪 org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, java.lang.Class<?>, boolean)
源码:
public static boolean canApply ( Pointcut pc, Class< ? > targetClass, boolean hasIntroductions) {
Assert. notNull ( pc, "Pointcut must not be null" ) ;
if ( ! pc. getClassFilter ( ) . matches ( targetClass) ) {
return false ;
}
MethodMatcher methodMatcher = pc. getMethodMatcher ( ) ;
if ( methodMatcher == MethodMatcher. TRUE) {
return true ;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if ( methodMatcher instanceof IntroductionAwareMethodMatcher ) {
introductionAwareMethodMatcher = ( IntroductionAwareMethodMatcher) methodMatcher;
}
Set< Class< ? >> classes = new LinkedHashSet < > ( ) ;
if ( ! Proxy. isProxyClass ( targetClass) ) {
classes. add ( ClassUtils. getUserClass ( targetClass) ) ;
}
classes. addAll ( ClassUtils. getAllInterfacesForClassAsSet ( targetClass) ) ;
for ( Class< ? > clazz : classes) {
Method[ ] methods = ReflectionUtils. getAllDeclaredMethods ( clazz) ;
for ( Method method : methods) {
if ( introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher. matches ( method, targetClass, hasIntroductions) :
methodMatcher. matches ( method, targetClass) ) {
return true ;
}
}
}
return false ;
}
该方法的作用是匹配给定的切入点是否完全适用于给定的类,通过MethodMatcher 来匹配,这里的MethodMatcher 本身就是PointBeanFactoryTransactionAttributeSourceAdvisor
,它通过父类TransactionAttributeSourcePointcut#matches
完成匹配,如下:
TransactionAttributeSourcePointcut 查找@Transactional注解
下面是 TransactionAttributeSourcePointcut 进行匹配的源码:
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
@Override
public boolean matches ( Method method, @Nullable Class< ? > targetClass) {
if ( targetClass != null && TransactionalProxy. class . isAssignableFrom ( targetClass) ) {
return false ;
}
TransactionAttributeSource tas = getTransactionAttributeSource ( ) ;
return ( tas == null || tas. getTransactionAttribute ( method, targetClass) != null) ;
}
这里getTransactionAttributeSource();
方法由子类BeanFactoryTransactionAttributeSourceAdvisor
来实现,目的是获取TransactionAttributeSource
对象,然后调用tas.getTransactionAttribute获取TransactionAttribute,不为空说明方法是支持@Transational的。
tas.getTransactionAttribute
方法中会先通过类名和方法名构建一个key,从缓存中 attributeCache 获取TransactionAttribute,如果没有,就通过AnnotationTransactionAttributeSource#determineTransactionAttribute
去解析当前Method 的@Transactional封装成 TransactionAttribute,并装入缓存。源码如下;
org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#getTransactionAttribute
public TransactionAttribute getTransactionAttribute ( Method method, @Nullable Class< ? > targetClass) {
if ( method. getDeclaringClass ( ) == Object. class ) {
return null;
}
Object cacheKey = getCacheKey ( method, targetClass) ;
TransactionAttribute cached = this . attributeCache. get ( cacheKey) ;
if ( cached != null) {
if ( cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
return cached;
}
}
else {
TransactionAttribute txAttr = computeTransactionAttribute ( method, targetClass) ;
if ( txAttr == null) {
this . attributeCache. put ( cacheKey, NULL_TRANSACTION_ATTRIBUTE) ;
}
else {
String methodIdentification = ClassUtils. getQualifiedMethodName ( method, targetClass) ;
if ( txAttr instanceof DefaultTransactionAttribute ) {
( ( DefaultTransactionAttribute) txAttr) . setDescriptor ( methodIdentification) ;
}
if ( logger. isDebugEnabled ( ) ) {
logger. debug ( "Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr) ;
}
this . attributeCache. put ( cacheKey, txAttr) ;
}
return txAttr;
}
}
我们看一下 computeTransactionAttribute 方法的源码
protected TransactionAttribute computeTransactionAttribute ( Method method, @Nullable Class< ? > targetClass) {
if ( allowPublicMethodsOnly ( ) && ! Modifier. isPublic ( method. getModifiers ( ) ) ) {
return null;
}
Method specificMethod = AopUtils. getMostSpecificMethod ( method, targetClass) ;
TransactionAttribute txAttr = findTransactionAttribute ( specificMethod) ;
if ( txAttr != null) {
return txAttr;
}
txAttr = findTransactionAttribute ( specificMethod. getDeclaringClass ( ) ) ;
if ( txAttr != null && ClassUtils. isUserLevelMethod ( method) ) {
return txAttr;
}
if ( specificMethod != method) {
txAttr = findTransactionAttribute ( method) ;
if ( txAttr != null) {
return txAttr;
}
txAttr = findTransactionAttribute ( method. getDeclaringClass ( ) ) ;
if ( txAttr != null && ClassUtils. isUserLevelMethod ( method) ) {
return txAttr;
}
}
return null;
}
首先从方法上找事务注解,如果没有就从类上面去找,如果始终找不到,就返回一个null,该方法不会被代理。最终代码来到AnnotationTransactionAttributeSource#determineTransactionAttribute
protected TransactionAttribute determineTransactionAttribute ( AnnotatedElement element) {
for ( TransactionAnnotationParser annotationParser : this . annotationParsers) {
TransactionAttribute attr = annotationParser. parseTransactionAnnotation ( element) ;
if ( attr != null) {
return attr;
}
}
return null;
}
查找事务属性工作交给 AnnotationTransactionAttributeSource
完成,它委托了TransactionAnnotationParser#parseTransactionAnnotation
来实现。默认使用解析器SpringTransactionAnnotationParser
它支持Spring的@Transactional注解。
SpringTransactionAnnotationParser 解析 @Transcational注解
继续跟踪 SpringTransactionAnnotationParser#parseTransactionAnnotation
源码如下:
public TransactionAttribute parseTransactionAnnotation ( AnnotatedElement element) {
AnnotationAttributes attributes = AnnotatedElementUtils. findMergedAnnotationAttributes (
element, Transactional. class , false , false ) ;
if ( attributes != null) {
return parseTransactionAnnotation ( attributes) ;
}
else {
return null;
}
}
找到AnnotationAttributes 之后调用parseTransactionAnnotation
进行解析,把事务的配置封装成RuleBasedTransactionAttribute
返回,源码如下
protected TransactionAttribute parseTransactionAnnotation ( AnnotationAttributes attributes) {
RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute ( ) ;
Propagation propagation = attributes. getEnum ( "propagation" ) ;
rbta. setPropagationBehavior ( propagation. value ( ) ) ;
Isolation isolation = attributes. getEnum ( "isolation" ) ;
rbta. setIsolationLevel ( isolation. value ( ) ) ;
rbta. setTimeout ( attributes. getNumber ( "timeout" ) . intValue ( ) ) ;
rbta. setReadOnly ( attributes. getBoolean ( "readOnly" ) ) ;
rbta. setQualifier ( attributes. getString ( "value" ) ) ;
List< RollbackRuleAttribute> rollbackRules = new ArrayList < > ( ) ;
for ( Class< ? > rbRule : attributes. getClassArray ( "rollbackFor" ) ) {
rollbackRules. add ( new RollbackRuleAttribute ( rbRule) ) ;
}
for ( String rbRule : attributes. getStringArray ( "rollbackForClassName" ) ) {
rollbackRules. add ( new RollbackRuleAttribute ( rbRule) ) ;
}
for ( Class< ? > rbRule : attributes. getClassArray ( "noRollbackFor" ) ) {
rollbackRules. add ( new NoRollbackRuleAttribute ( rbRule) ) ;
}
for ( String rbRule : attributes. getStringArray ( "noRollbackForClassName" ) ) {
rollbackRules. add ( new NoRollbackRuleAttribute ( rbRule) ) ;
}
rbta. setRollbackRules ( rollbackRules) ;
return rbta;
}
总结
本篇文章主要是判断类是否有被注解@Transcationl从而决定是否可用被代理,整体流程如下:
在 TxNamespaceHandler 注册了AnnotationDrivenBeanDefinitionParser用来解析事务注解配置 在AnnotationDrivenBeanDefinitionParser中创建 InfrastructureAdvisorAutoProxyCreator,其本身是个BeanPostPorcessor,还创建了 TransactionAttributeSource , TransactionInterceptor , TransactionAttributeSourceAdvisor 在Bean实例化的过程中调用InfrastructureAdvisorAutoProxyCreator#postProcessAfterInitialization 来解析Bean是否有@Transational,从而判断是否要进行增强创建代理。 在AutoProxyCreator 内部的 AopUtils#canApply 方法中通过 BeanFactoryTransactionAttributeSourceAdvisor的TransactionAttributeSourcePointcut切入点的matches方法中进行解析方法上的@Transactional 来决定是否要增强。 该方法获取到BeanFactoryTransactionAttributeSourceAdvisor 中的AnnotationTransactionAttributeSource,调用其getTransactionAttribute来解析。内部通过 SpringTransactionAnnotationParser#parseTransactionAnnotation来解析 方法上的@Transactional,如果方法上没有就去类上找,或者去父类的方法和类上找。 如果找到了就缓存到AbstractFallbackTransactionAttributeSource的attributeCache中,如果没找到说明这类不需要被事务增强。
文章结束,喜欢就给个好评吧,你的肯定是我最大的动力哦!!!