天天看點

Spring源碼剖析-事務源碼之@Transactionl解析前言事務配置案例事務注解原理事務标簽解析器解析目前方法是否要被代理總結

前言

在上一章我們分析了Spring的AOP的源碼,本篇文章是對事務的源碼分析,我們都知道事務的管理是基于AOP實作的,是以有了上一篇的鋪墊這一章會比較簡單一點。

事務的源碼我會分兩章寫,一張寫Transcational的解析,一張寫事務的執行流程。先上一個圖,待會兒可以根據這個圖來看源碼

Spring源碼剖析-事務源碼之@Transactionl解析前言事務配置案例事務注解原理事務标簽解析器解析目前方法是否要被代理總結

事務配置案例

配置事務管理器,開啟注解事務支援

<!-- 開啟事務支援 -->
    <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的方式幫我們開啟事務,送出事務或是復原事務操作,不僅簡化了我們的工作難度,避免重複事務邏輯處理,同時也減少了代碼的侵入,達到代碼解耦和的效果。

Spring源碼剖析-事務源碼之@Transactionl解析前言事務配置案例事務注解原理事務标簽解析器解析目前方法是否要被代理總結

事務的管理是基于AOP實作,AOP的原理又是動态代理,也就是說被标記了@Transactional的類都會建立代理類來實作事務增強,建立代理後,方法的真實調用都是走代理對象。那麼Spring如何知道要對哪些類哪些方法進行代理?Spring會把 @Transactional 注解作為切點,這樣就知道哪些方法需要被代理 。至于代理類的建立是在Bean的執行個體化過程中完成,在上一篇文章有說道,見:《AOP原理》

Spring源碼剖析-事務源碼之@Transactionl解析前言事務配置案例事務注解原理事務标簽解析器解析目前方法是否要被代理總結

事務标簽解析器

NamespaceHandlerSupport 注冊解析器

因為注解事務支援需要在XML中開啟 ,是以對于事務來說可以分為兩部分 :一是事務配置解析 ,二是代理建立。在上一章節我們就有提到,對于xml中的所有namespace都有對應的解析器, 在Spring中有一個接口叫 NamespaceHandlerSupport ,它提供了Spring xml配置的namespace的解析支援。

Spring源碼剖析-事務源碼之@Transactionl解析前言事務配置案例事務注解原理事務标簽解析器解析目前方法是否要被代理總結

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() {
    }
	//解析元素:Element就是 <tx:annotation-driven/>
 public BeanDefinition parse(Element element, ParserContext parserContext) {
 		//注冊事務監聽
        this.registerTransactionalEventListenerFactory(parserContext);
        //判斷model,預設是proxy,走else
        String mode = element.getAttribute("mode");
        if ("aspectj".equals(mode)) {
            this.registerTransactionAspect(element, parserContext);
        } else {
            //建立自動代理建立器(InfrastructureAdvisorAutoProxyCreator)
          AnnotationDrivenBeanDefinitionParser.AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
        }

        return null;
    }
           

AopAutoProxyConfigurer 建立事務核心類

這個parse解析方法注冊了事務監聽器後就判斷了mode,預設使用的是proxy代理方式,即調用

configureAutoProxyCreator

方法,一路跟下去

/**
	 * Inner class to just introduce an AOP framework dependency when actually in proxy mode.
	 */
	private static class AopAutoProxyConfigurer {

		public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
			//注冊一個自動代理建立器 InfrastructureAdvisorAutoProxyCreator
			AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

			String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
			//判斷容器中是否已經注冊了 internalTransactionAdvisor
			if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
				Object eleSource = parserContext.extractSource(element);
				//【标記1】注冊 TransactionAttributeSource
				// Create the TransactionAttributeSource definition.
				RootBeanDefinition sourceDef = new RootBeanDefinition(
						"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
				sourceDef.setSource(eleSource);
				sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
				//【标記2】注冊 TransactionInterceptor
				// Create the TransactionInterceptor definition.
				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);
				//【标記3】 注冊一個TransactionAttributeSourceAdvisor
				// Create the BeanFactoryTransactionAttributeSourceAdvisor definition.
				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是否可以被增強

Spring源碼剖析-事務源碼之@Transactionl解析前言事務配置案例事務注解原理事務标簽解析器解析目前方法是否要被代理總結

解析目前方法是否要被代理

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)) {
        	//擷取增強器 Advisors
            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();
        //找到目前beanClass适用的增強器
        List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        this.extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
        }

        return eligibleAdvisors;
    }
           

我們重點來看一下它是如何比對适合目前Bean的增強器的。見:

AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply

//搜尋能應用于目前beanClass的 Advisors
	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 切點的Advisor
			PointcutAdvisor pca = (PointcutAdvisor) advisor;
			return canApply(pca.getPointcut(), targetClass, hasIntroductions);
		}
		else {
			// It doesn't have a pointcut so we assume it applies.
			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");
		//class 過濾器 ,預設直接傳回true
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}
		//方法比對器,其實就是  BeanFactoryTransactionAttributeSourceAdvisor
		MethodMatcher methodMatcher = pc.getMethodMatcher();
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}

		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}
		//擷取到要被建立代理的原生類的 class,并把其接口添加到classes中
		Set<Class<?>> classes = new LinkedHashSet<>();
		if (!Proxy.isProxyClass(targetClass)) {
			classes.add(ClassUtils.getUserClass(targetClass));
		}
		classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
		//處理classes
		for (Class<?> clazz : classes) {
		//拿到原生類,或其接口的所有方法聲明
			Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
			for (Method method : methods) {
				//通過 MethodMatcher 比對,走的是 TransactionAttributeSourcePointcut#matches方法
				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;
		}
		//擷取 BeanFactoryTransactionAttributeSourceAdvisor 中的AnnotationTransactionAttributeSource
		TransactionAttributeSource tas = getTransactionAttributeSource();
		//判斷TransactionAttribute不為空,說明該targetClass的method是有事務注解的
		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;
		}

		// First, see if we have a cached value.
		//建構一個緩存key
		Object cacheKey = getCacheKey(method, targetClass);
		//從緩存中擷取TransactionAttribute 
		TransactionAttribute cached = this.attributeCache.get(cacheKey);
		if (cached != null) {
			// Value will either be canonical value indicating there is no transaction attribute,
			// or an actual transaction attribute.
			if (cached == NULL_TRANSACTION_ATTRIBUTE) {
				return null;
			}
			else {
			//傳回緩存中的TransactionAttribute
				return cached;
			}
		}
		else {
			// We need to work it out.
			//查找和解析method的事務注解,封裝成TransactionAttribute
			TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
			// Put it in the cache.
			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);
				}
				//把 TransactionAttribute  放入緩存attributeCache
				this.attributeCache.put(cacheKey, txAttr);
			}
			return txAttr;
		}
	}

           

我們看一下 computeTransactionAttribute 方法的源碼

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
		// Don't allow no-public methods as required.
		//預設隻能是public方法進行事務代理,但是可以通過allowPublicMethodsOnly方法修改
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}

		// The method may be on an interface, but we need attributes from the target class.
		// If the target class is null, the method will be unchanged.
		//有可能找到的是接口方法,但是需要的是實作類的方法
		Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

		// First try is the method in the target class.
		//【重要】首先從方法上找事務注解,有就傳回,沒有再找類上的事務注解,是以方法上的事務注解優先級高
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) {
			return txAttr;
		}

		// Second try is the transaction attribute on the target class.
		//[重要]然後從目前類上找注解
		txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
		if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
			return txAttr;
		}
		//如果最終的目标方法和目前方法不一緻,從目前方法上找
		if (specificMethod != method) {
			//回退是看原方法
			// Fallback is to look at the original method.
			txAttr = findTransactionAttribute(method);
			if (txAttr != null) {
				return txAttr;
			}
			// Last fallback is the class of the original method.
			//最後一個回退是原始方法的類
			txAttr = findTransactionAttribute(method.getDeclaringClass());
			if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
				return txAttr;
			}
		}
		//實在找不到,傳回一個null,該方法不會被代理
		return null;
	}
           

首先從方法上找事務注解,如果沒有就從類上面去找,如果始終找不到,就傳回一個null,該方法不會被代理。最終代碼來到

AnnotationTransactionAttributeSource#determineTransactionAttribute

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
		for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
			//委托 TransactionAnnotationParser(SpringTransactionAnnotationParser) 去解析事務注解
			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) {
		//通過AnnotatedElementUtils查找 方法上的 Transactional注解,解析并封裝成AnnotationAttributes 
		//查找方法或者類上的@Transactional注解,沒找到,那麼會繼續在父類的方法上,和類上找。
		//最終将使用找到的第一個注解資料
		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進而決定是否可用被代理,整體流程如下:

  1. 在 TxNamespaceHandler 注冊了AnnotationDrivenBeanDefinitionParser用來解析事務注解配置
  2. 在AnnotationDrivenBeanDefinitionParser中建立 InfrastructureAdvisorAutoProxyCreator,其本身是個BeanPostPorcessor,還建立了 TransactionAttributeSource , TransactionInterceptor , TransactionAttributeSourceAdvisor
  3. 在Bean執行個體化的過程中調用InfrastructureAdvisorAutoProxyCreator#postProcessAfterInitialization 來解析Bean是否有@Transational,進而判斷是否要進行增強建立代理。
  4. 在AutoProxyCreator 内部的 AopUtils#canApply 方法中通過 BeanFactoryTransactionAttributeSourceAdvisor的TransactionAttributeSourcePointcut切入點的matches方法中進行解析方法上的@Transactional 來決定是否要增強。
  5. 該方法擷取到BeanFactoryTransactionAttributeSourceAdvisor 中的AnnotationTransactionAttributeSource,調用其getTransactionAttribute來解析。内部通過 SpringTransactionAnnotationParser#parseTransactionAnnotation來解析 方法上的@Transactional,如果方法上沒有就去類上找,或者去父類的方法和類上找。
  6. 如果找到了就緩存到AbstractFallbackTransactionAttributeSource的attributeCache中,如果沒找到說明這類不需要被事務增強。

文章結束,喜歡就給個好評吧,你的肯定是我最大的動力哦!!!