我们在spring使用事务有三种方式,第一种使用xml配置的方式配置,第二种使用注解的方式配置,第三种使用编程的方式。 我们首先从xml配置开始

<tx:advice id="txAdvice" transaction-manager="txManager">
	<tx:attributes>
		<tx:method name="save*" propagation="REQUIRED" />
		<tx:method name="delete*" propagation="REQUIRED" />
		<tx:method name="update*" propagation="REQUIRED" />
		<tx:method name="*" propagation="SUPPORTS" read-only="true" />
	</tx:attributes>
</tx:advice>

<bean id="txManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource" />
</bean>

    上面是一段常见的xml配置事务的方式,而解析这些标签的命名空间处理器是由TxNamespaceHandler实现的,其注册的标签解析器如下

public void init() {
        //解析advice标签
		registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
		//解析注解事务标签
		registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
		//解析jta分布式事务标签
		registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
	}

    按照惯例,我们首先了解xml配置事务的分析,然后在分析注解事务,第一步,分析TxAdviceBeanDefinitionParser,下面是它的类图

在这里插入图片描述

public final BeanDefinition org.springframework.beans.factory.xml.AbstractBeanDefinitionParser.parse(Element element, ParserContext parserContext) {
        //具体的实现由子类实现
        //(*1*)
		AbstractBeanDefinition definition = parseInternal(element, parserContext);
		//BeanDefinition不为空,并且当前BeanDefinition不是被包含的BeanDefinition
		if (definition != null && !parserContext.isNested()) {
			try {
			    //解析id,获取beanName
				String id = resolveId(element, definition, parserContext);
				if (!StringUtils.hasText(id)) {
					parserContext.getReaderContext().error(
							"Id is required for element '" + parserContext.getDelegate().getLocalName(element)
									+ "' when used as a top-level tag", element);
				}
				String[] aliases = null;
				//解析别名
				if (shouldParseNameAsAliases()) {
					String name = element.getAttribute(NAME_ATTRIBUTE);
					if (StringUtils.hasLength(name)) {
						aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));
					}
				}
				BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
				//注册BeanDefinition
				registerBeanDefinition(holder, parserContext.getRegistry());
				//触发事件,循环调用事件监听器
				if (shouldFireEvents()) {
					BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder);
					postProcessComponentDefinition(componentDefinition);
					parserContext.registerComponent(componentDefinition);
				}
			}
			catch (BeanDefinitionStoreException ex) {
				parserContext.getReaderContext().error(ex.getMessage(), element);
				return null;
			}
		}
		return definition;
	}
	
	
	//(*1*)
	protected final AbstractBeanDefinition org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser.parseInternal(Element element, ParserContext parserContext) {
	    //创建GenericBeanDefinition(这是一个通用BeanDefinition,常用于xml配置的bean)构建器
		BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
		//获取父配置的id名
		String parentName = getParentName(element);
		if (parentName != null) {
		    //设置父配置id名
			builder.getRawBeanDefinition().setParentName(parentName);
		}
		//这个方法由子类TxAdviceBeanDefinitionParser实现,返回TransactionInterceptor事务拦截器,这是一个实现了MethodInterceptor
		//接口的类
		Class<?> beanClass = getBeanClass(element);
		if (beanClass != null) {
			builder.getRawBeanDefinition().setBeanClass(beanClass);
		}
		else {
			String beanClassName = getBeanClassName(element);
			if (beanClassName != null) {
				builder.getRawBeanDefinition().setBeanClassName(beanClassName);
			}
		}
		//设置数据的来源
		builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
		//如果当前BeanDefinition是被包含的,那么继承包含BeanDefinition的生命周期
		if (parserContext.isNested()) {
			// Inner bean definition must receive same scope as containing bean.
			builder.setScope(parserContext.getContainingBeanDefinition().getScope());
		}
		//设置默认的懒加载设置
		if (parserContext.isDefaultLazyInit()) {
			// Default-lazy-init applies to custom bean definitions as well.
			builder.setLazyInit(true);
		}
		//这才是真正解析标签元素数据的地方
		doParse(element, parserContext, builder);
		return builder.getBeanDefinition();
	}

    我们从上面的代码看到,spring准备构建的BeanDefinition是TransactionInterceptor,这个拦截器实现了MethodInterceptor,这拦截器的逻辑我们放在后面分析,我继续往下分析advice标签的解析

protected void org.springframework.transaction.config.TxAdviceBeanDefinitionParser.doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
        //设置transactionManager属性,解析元素的transaction-manager属性,如果没有,就使用默认的transactionManager作为事务名
		builder.addPropertyReference("transactionManager", TxNamespaceHandler.getTransactionManagerName(element));

        //获取attributes标签
		List<Element> txAttributes = DomUtils.getChildElementsByTagName(element, ATTRIBUTES_ELEMENT);
		//attributes标签只允许一个
		if (txAttributes.size() > 1) {
			parserContext.getReaderContext().error(
					"Element <attributes> is allowed at most once inside element <advice>", element);
		}
		else if (txAttributes.size() == 1) {
			// Using attributes source.
			Element attributeSourceElement = txAttributes.get(0);
			//解析并创建属性源BeanDefinition
			//(*1*)
			RootBeanDefinition attributeSourceDefinition = parseAttributeSource(attributeSourceElement, parserContext);
			//设置事务属性源
			builder.addPropertyValue("transactionAttributeSource", attributeSourceDefinition);
		}
		else {
			// Assume annotations source.
			//如果没有设置事务属性,那么只好使用注解事务属性源
			builder.addPropertyValue("transactionAttributeSource",
					new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource"));
		}
	}
	
	
	//(*1*)
	private RootBeanDefinition parseAttributeSource(Element attrEle, ParserContext parserContext) {
	    //获取method标签元素
		List<Element> methods = DomUtils.getChildElementsByTagName(attrEle, METHOD_ELEMENT);
		//用于维护方法名表达式与对应事务属性的关系,RuleBasedTransactionAttribute的继承结构如下图
		ManagedMap<TypedStringValue, RuleBasedTransactionAttribute> transactionAttributeMap =
			new ManagedMap<TypedStringValue, RuleBasedTransactionAttribute>(methods.size());
		transactionAttributeMap.setSource(parserContext.extractSource(attrEle));

		for (Element methodEle : methods) {
		    //获取name属性,比如本例中的save*,update*等
			String name = methodEle.getAttribute(METHOD_NAME_ATTRIBUTE);
			//使用TypedStringValue进行包装
			TypedStringValue nameHolder = new TypedStringValue(name);
			//设置当前name值的来源
			nameHolder.setSource(parserContext.extractSource(methodEle));
            
            //构建基于规则的事务属性对象
			RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute();
			//解析propagation获取事务传播属性
			String propagation = methodEle.getAttribute(PROPAGATION_ATTRIBUTE);
			//解析isolation获取隔离级别
			String isolation = methodEle.getAttribute(ISOLATION_ATTRIBUTE);
			//解析timeout获取事务超时时间
			String timeout = methodEle.getAttribute(TIMEOUT_ATTRIBUTE);
			//read-only是否只读
			String readOnly = methodEle.getAttribute(READ_ONLY_ATTRIBUTE);
			//设置传播属性值(转换成int类型)
			if (StringUtils.hasText(propagation)) {
				attribute.setPropagationBehaviorName(RuleBasedTransactionAttribute.PREFIX_PROPAGATION + propagation);
			}
			//设置隔离机制
			if (StringUtils.hasText(isolation)) {
				attribute.setIsolationLevelName(RuleBasedTransactionAttribute.PREFIX_ISOLATION + isolation);
			}
			//设置事务超时时间
			if (StringUtils.hasText(timeout)) {
				try {
					attribute.setTimeout(Integer.parseInt(timeout));
				}
				catch (NumberFormatException ex) {
					parserContext.getReaderContext().error("Timeout must be an integer value: [" + timeout + "]", methodEle);
				}
			}
			//设置只读属性
			if (StringUtils.hasText(readOnly)) {
				attribute.setReadOnly(Boolean.valueOf(methodEle.getAttribute(READ_ONLY_ATTRIBUTE)));
			}

			List<RollbackRuleAttribute> rollbackRules = new LinkedList<RollbackRuleAttribute>();
			//设置rollback-for,设置需要回滚的异常类型
			if (methodEle.hasAttribute(ROLLBACK_FOR_ATTRIBUTE)) {
			    //获取rollback-for属性值,按逗号分割,包装成RollbackRuleAttribute对象存储到rollbackRules集合中
				String rollbackForValue = methodEle.getAttribute(ROLLBACK_FOR_ATTRIBUTE);
				addRollbackRuleAttributesTo(rollbackRules,rollbackForValue);
			}
			//no-rollback-for 设置不需要回滚的异常类型
			if (methodEle.hasAttribute(NO_ROLLBACK_FOR_ATTRIBUTE)) {
			    //获取no-rollback-for属性值,按逗号分割,包装成NoRollbackRuleAttribute对象存储到rollbackRules集合中
				String noRollbackForValue = methodEle.getAttribute(NO_ROLLBACK_FOR_ATTRIBUTE);
				addNoRollbackRuleAttributesTo(rollbackRules,noRollbackForValue);
			}
			//设置回滚规则
			attribute.setRollbackRules(rollbackRules);
            //储存到transactionAttributeMap集合中
			transactionAttributeMap.put(nameHolder, attribute);
		}
        //构建NameMatchTransactionAttributeSource事务属性源
		RootBeanDefinition attributeSourceDefinition = new RootBeanDefinition(NameMatchTransactionAttributeSource.class);
		attributeSourceDefinition.setSource(parserContext.extractSource(attrEle));
		//将刚才获取的事务属性map设置到事务属性源中
		attributeSourceDefinition.getPropertyValues().add("nameMap", transactionAttributeMap);
		return attributeSourceDefinition;
	}

    上面一段代码中为每个method标签创建了一个RuleBasedTransactionAttribute对象,将method标签上的属性都设置到这个对象中,所以TransactionAttribute就是一个用于承载事务属性数据的模型,下面是RuleBasedTransactionAttribute的继承结构

在这里插入图片描述

TransactionDefinition 主要定义一些全局静态属性,比如事务传播属性值,隔离级别值,定义获取隔离级别,事务传播属性,超时时间的能力,看到这个TransactionDefinition,就应该想到BeanDefinition,都是用于承载属性定义的模型对象

TransactionAttribute 增加了一些qualifier,qualifier我们以前在分析bean的时候分析过,这个东西是用来筛选事务管理器,比如通过当前事务定义的qualifier值与对应事务管理器中@Qualifier进行对比是否符合条件,或者beanName对比等,忘记的同学可以翻看bean创建的那一章节,这里就不过多的赘述了

DefaultTransactionDefinition 提供一些扩展属性定义,比如代表事务传播的前缀,隔离级别的前缀等等

DefaultTransactionAttribute 实现了一些基本方法,比如是否定义哪些异常能够回滚,默认是RuntimeException,Error

RuleBasedTransactionAttribute 支持自定义异常的回滚

    我们看到spring把每个方法对应的RuleBasedTransactionAttribute以方法匹配模式为key,RuleBasedTransactionAttribute为值的方式存储到了一个map中,最后设置到一个叫NameMatchTransactionAttributeSource的对象中,这个类的继承结构如下

在这里插入图片描述

TransactionAttributeSource 定义通过方法,对应class类获取事务属性的能力

NameMatchTransactionAttributeSource TransactionAttributeSource的实现类,通过方法名匹配来获取对应的事务属性

    下面是NameMatchTransactionAttributeSource的getTransactionAttribute方法

public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
        //如果不是用户定义的方法,直接返回,比如说桥方法,虚拟机生成的,groovy.lang.GroovyObject类的方法
		if (!ClassUtils.isUserLevelMethod(method)) {
			return null;
		}

		// Look for direct name match.
		//获取方法名
		String methodName = method.getName();
		//直接通过方法获取看看能不能获取
		TransactionAttribute attr = this.nameMap.get(methodName);
        //不能获取,那么就只能通过简单匹配的方式获取了,简单匹配xxx*,xxx*yyy,*xxx这种模式
		if (attr == null) {
			// Look for most specific name match.
			String bestNameMatch = null;
			for (String mappedName : this.nameMap.keySet()) {
				if (isMatch(methodName, mappedName) &&
						(bestNameMatch == null || bestNameMatch.length() <= mappedName.length())) {
					attr = this.nameMap.get(mappedName);
					bestNameMatch = mappedName;
				}
			}
		}

		return attr;
	}

    advice标签解析的时候创建了一个TransactionInterceptor的BeanDefinition,并给这个BeanDefinition注入事务属性源,事务管理器,下面是xml配置的advice标签的解析过程时序图和事务拦截器的类图

在这里插入图片描述

在这里插入图片描述

    xml配置解析advice标签的分析到此结束,接下来继续看annotation-driven标签的解析,对应的解析器为AnnotationDrivenBeanDefinitionParser

<tx:annotation-driven transaction-manager="txManager" />

<bean id="txManager"
	class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
	<property name="dataSource" ref="dataSource" />
</bean>

public BeanDefinition org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser.parse(Element element, ParserContext parserContext) {
        //注册事务事件监听器TransactionalEventListenerFactory
		//事件监听工厂在refresh方法的
		//org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(ConfigurableListableBeanFactory)
		//中初始化完非懒加载单例bean后调用,用于创建ApplicationListener
		//创建一个ApplicationListenerMethodTransactionalAdapter监听器
		registerTransactionalEventListenerFactory(parserContext);
		String mode = element.getAttribute("mode");
		//如果模式是aspectj,那么spring将启用aspectj框架进行切面代理,使用特殊的编译器在编译器进行代理
		if ("aspectj".equals(mode)) {
			// mode="aspectj"
			registerTransactionAspect(element, parserContext);
		}
		else {
		    //这是我们常用的模式,使用JDK或者cglib代理
			// mode="proxy"
			AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
		}
		return null;
	}

    对于注解的aop有两种模式,一种是aspectj,另一种是proxy,proxy是我们默认使用的,aspectj需要aspectj特殊编译器(ajc)的支持,在编译期进行aop代理,感兴趣的同学可以去研究研究它的语法。文档地址:https://www.eclipse.org/aspectj/doc/released/progguide/index.html 或者一个入门aspectj的博客:https://blog.mythsman.com/2017/12/21/1/

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {

            //注册InfrastructureAdvisorAutoProxyCreator后置处理器
			AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
            //beanName
			String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
			if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
				Object eleSource = parserContext.extractSource(element);

				// Create the TransactionAttributeSource definition.
				//构建注解事务属性源
				RootBeanDefinition sourceDef = new RootBeanDefinition(
						"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
				sourceDef.setSource(eleSource);
				sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				//使用生成的beanName进行注册
				String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

				// Create the TransactionInterceptor definition.
				//创建TransactionInterceptor的BeanDefinition,这个拦截器我们在分析xml配置的时候讲到过,其细节不再赘述
				RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
				interceptorDef.setSource(eleSource);
				interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				//给TransactionInterceptor设置事务管理器属性
				registerTransactionManager(element, interceptorDef);
				//给TransactionInterceptor设置事务属性源
				interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				//注册到BeanFactory
				String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);

				// Create the TransactionAttributeSourceAdvisor definition.
				//创建关于事务的advisor
				RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
				advisorDef.setSource(eleSource);
				//标记为基础设施角色,这种角色类型的类不会被后置处理
				advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				//设置事务属性源
				advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				//设置通知拦截的beanName
				advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
				if (element.hasAttribute("order")) {
					advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
				}
				//注册到BeanFactory
				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);
			}
		}

    从上面的代码中我们可以看到spring解析annotation-driven时向BeanFactory中注入了后置处理器InfrastructureAdvisorAutoProxyCreator,事务属性源AnnotationTransactionAttributeSource,通知TransactionInterceptor,通知器BeanFactoryTransactionAttributeSourceAdvisor,对应事务这个advisor它所持有的切点是一个继承了StaticMethodMatcherPointcut的类,所以可以想象到对应的ClassFilter是一个ClassFilter.TRUE,AnnotationTransactionAttributeSource我们参考前面xml配置的NameMatchTransactionAttributeSource就可以猜测到它具有通过某种方式获取TransactionAttribute的能力。 下面我们先来看看InfrastructureAdvisorAutoProxyCreator的类图

在这里插入图片描述

    我们发现这个类的继承结构和我们前面分析注解aop后置处理器AnnotationAwareAspectJAutoProxyCreator很像,InfrastructureAdvisorAutoProxyCreator只是 重写了isEligibleAdvisorBean,initBeanFactory方法,其他的和AnnotationAwareAspectJAutoProxyCreator一样,所以对于它怎么获取advisor的,这不再过多的赘述了,现在我们来看看AnnotationTransactionAttributeSource是怎么获取TransactionAttribute的

public TransactionAttribute org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.getTransactionAttribute(Method method, Class<?> targetClass) {
		// First, see if we have a cached value.
		Object cacheKey = getCacheKey(method, targetClass);
		//从缓存中获取
		Object 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 {
				return (TransactionAttribute) cached;
			}
		}
		else {
			// We need to work it out.
			//(*1*)
			TransactionAttribute txAtt = computeTransactionAttribute(method, targetClass);
			// Put it in the cache.
			if (txAtt == null) {
				this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
			}
			else {
				if (logger.isDebugEnabled()) {
					Class<?> classToLog = (targetClass != null ? targetClass : method.getDeclaringClass());
					logger.debug("Adding transactional method '" + classToLog.getSimpleName() + "." +
							method.getName() + "' with attribute: " + txAtt);
				}
				this.attributeCache.put(cacheKey, txAtt);
			}
			return txAtt;
		}
	}
	
	
	//(*1*)
	protected TransactionAttribute org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource.computeTransactionAttribute(Method method, Class<?> targetClass) {
		// Don't allow no-public methods as required.
		//如果不允许代理非publi的方法,那么直接跳过
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}

		// Ignore CGLIB subclasses - introspect the actual user class.
		//获取用户定义的类,如果是CGLIB代理的类,那么getSuperClass
		Class<?> userClass = ClassUtils.getUserClass(targetClass);
		// 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.
		//获取指定userClass中的方法对象
		Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
		// If we are dealing with method with generic parameters, find the original method.
		//找到被桥的方法
		specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);

		// First try is the method in the target class.
		//首先从目标方法上寻找@Transaction并解析
		TransactionAttribute txAtt = findTransactionAttribute(specificMethod);
		if (txAtt != null) {
			return txAtt;
		}

		// Second try is the transaction attribute on the target class.
		//如果第一步失败,那么从定义这个方法的类上面找
		txAtt = findTransactionAttribute(specificMethod.getDeclaringClass());
		if (txAtt != null) {
			return txAtt;
		}
        //如果还是失败,那么从原始指定的方法上找,要是还是失败,那么从原始方法定义的类上找
		if (specificMethod != method) {
			// Fallback is to look at the original method.
			txAtt = findTransactionAttribute(method);
			if (txAtt != null) {
				return txAtt;
			}
			// Last fallback is the class of the original method.
			return findTransactionAttribute(method.getDeclaringClass());
		}
		//实在找不到,返回null
		return null;
	}

    spring的代码之所以优秀除了使用各种设计模式之外,他们在代码的处理上也是职责清晰,不同职责的代码放在不同的方法中,避免一个方法处理过多的职责,如果把方法看成是一个接口的话,那么这就是设计模式中接口单一原则

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement ae) {
		if (ae.getAnnotations().length > 0) {
		    //一般产常用的的注解解析器是SpringTransactionAnnotationParser,其他两个分别是JtaTransactionAnnotationParser(用于jta分布式事务注解
		    // javax.transaction.Transactional),
		    //Ejb3TransactionAnnotationParser(用于ejb)
		    //这里我们只分析SpringTransactionAnnotationParser的解析
			for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
				TransactionAttribute attr = annotationParser.parseTransactionAnnotation(ae);
				if (attr != null) {
					return attr;
				}
			}
		}
		return null;
	}

    解析spring事务注解@org.springframework.transaction.annotation.Transactional

public TransactionAttribute org.springframework.transaction.annotation.SpringTransactionAnnotationParser.parseTransactionAnnotation(AnnotatedElement ae) {
        //获取@Transactional的合并属性名-》属性值,在spring中元注解与注解具有父子级关系,我们在分析spring通过注解扫描
        //bean时较为详细的探讨这个问题,感兴趣的同学可以翻开之前的文章,或者自己研究代码
		AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(ae, Transactional.class);
		if (attributes != null) {
		    //(*1*)
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}
	
	//(*1*)
	protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
	    //又看到我们熟悉的RuleBasedTransactionAttribute了,我们在分析xml配置aop的时候对其较详细的进行了讲解
		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"));
		//设置Qualifier筛选器
		rbta.setQualifier(attributes.getString("value"));
		ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<RollbackRuleAttribute>();
		//解析回滚异常
		Class<?>[] rbf = attributes.getClassArray("rollbackFor");
		for (Class<?> rbRule : rbf) {
			RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		//解析回滚异常
		String[] rbfc = attributes.getStringArray("rollbackForClassName");
		for (String rbRule : rbfc) {
			RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		//解析非回滚异常
		Class<?>[] nrbf = attributes.getClassArray("noRollbackFor");
		for (Class<?> rbRule : nrbf) {
			NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		//解析非回滚异常
		String[] nrbfc = attributes.getStringArray("noRollbackForClassName");
		for (String rbRule : nrbfc) {
			NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		//设置事务回滚异常规则集合
		rbta.getRollbackRules().addAll(rollBackRules);
		return rbta;
	}

    ok,注解解析事务属性的分析就到这,下面分析事务拦截才是重头戏。不管是xml还是注解他们都使用了一个叫做TransactionInterceptor的通知拦截器

public Object invoke(final MethodInvocation invocation) throws Throwable {
	    //获取被代理类的Class对象
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

		// Adapt to TransactionAspectSupport's invokeWithinTransaction...
		//在事务中调用方法
		return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
			@Override
			public Object proceedWithInvocation() throws Throwable {
			    //驱动链条执行下一个拦截器
				return invocation.proceed();
			}
		});
	}
	

    事务调用方法

protected Object org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
			throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		//使用事务属性源获取事务属性,xml配置的事务源将以简单匹配的方式匹配方法(xxx*,xxx*yyy,*xxx)获取事务属性
		//注解事务属性源解析@Transaction注解的获取事务属性
		final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
		//获取事务管理器,从BeanFactory中获取,并通过@Qualifier筛选
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		//连接点标识 className + "." + methodName
		final String joinpointIdentification = methodIdentification(method, targetClass);
        
        //处理没有事务属性和管理器不是回调方式管理器的事务,我们本例中使用的管理器是DataSourceTransactionManager
        //它不是一个支持回调的事务
		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			//创建事务信息
			TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
			Object retVal = null;
			try {
				// This is an around advice: Invoke the next interceptor in the chain.
				// This will normally result in a target object being invoked.
				//继续向下一个拦截器执行
				retVal = invocation.proceedWithInvocation();
			}
			catch (Throwable ex) {
				// target invocation exception
				//发生异常,需要进行事务的回滚,恢复挂起事务等操作
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
			    //清理到当前线程中的事务信息
				cleanupTransactionInfo(txInfo);
			}
			//提交事务,恢复挂起事务
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		。。。。。。省略回调事务管理器的代码,在后面分析
	}

    我们站在事务门外看了下,大致了解到spring执行事务其实就是使用aop的环绕,抛出异常通知的结合。下一节,我们到事务的家里坐坐客,了解下spring是如果创建事务的。