Spring源码学习18

1.事务也是对方法的增强,所以最终也会创建代理对象;创建代理对象方法AbstractAutoProxyCreator.wrapIfNecessary;不熟悉的童鞋可以在Spring源码学习14、15、16、17回顾下;无论是通过tx:advice还是@Transaction注解方式实现事务,Spring最终都会将其封装为Advisor对象,可以看下AbstractAdvisorAutoProxyCreator.findCandidateAdvisors()方法的实现。

/**
	 * Find all eligible Advisor beans in the current bean factory,
	 * ignoring FactoryBeans and excluding beans that are currently in creation.
	 *
	 * 找到当前bean工厂中所有符合条件的Advisor bean,
	 * 忽略FactoryBeans并排除当前正在创建的bean。
	 * @return the list of {@link org.springframework.aop.Advisor} beans
	 * @see #isEligibleBean
	 */
	public List<Advisor> findAdvisorBeans() {
		// 如果cachedAdvisorBeanNames尚未确定,则定advisor的beanName
		String[] advisorNames = this.cachedAdvisorBeanNames;
		if (advisorNames == null) {
			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the auto-proxy creator apply to them!
			//不要在这里初始化FactoryBeans:我们需要保留所有常规bean
			//未初始化让自动代理创建者用于他们!

			//事务其实是一种特殊的增强,属于环绕型增强所以使用了MethodInterceptor做增强实现
			//通过tx:advice配置;最终通过<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
			//配置一起将tx:advice和pointcut封装成DefaultBeanFactoryPointcutAdvisor
			//所以这里能够获取到tx:advice配置的事务增强

			//通过<tx:annotation-driven transaction-manager="transactionManager"/>
			//配置实现的advisor最终为BeanFactoryTransactionAttributeSourceAdvisor
			//所以该方法也能够获取到通过注解实现事务增强的advisor。
			advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
					this.beanFactory, Advisor.class, true, false);
			this.cachedAdvisorBeanNames = advisorNames;
		}
		if (advisorNames.length == 0) {
			return new ArrayList<Advisor>();
		}

		List<Advisor> advisors = new ArrayList<Advisor>();
		for (String name : advisorNames) {
			if (isEligibleBean(name)) {
				if (this.beanFactory.isCurrentlyInCreation(name)) {
					if (logger.isDebugEnabled()) {
						logger.debug("Skipping currently created advisor '" + name + "'");
					}
				}
				else {
					try {
						//创建advisor并添加到advisors集合;并实例化advisor
						advisors.add(this.beanFactory.getBean(name, Advisor.class));
					}
					catch (BeanCreationException ex) {
						Throwable rootCause = ex.getMostSpecificCause();
						if (rootCause instanceof BeanCurrentlyInCreationException) {
							BeanCreationException bce = (BeanCreationException) rootCause;
							if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {
								if (logger.isDebugEnabled()) {
									logger.debug("Skipping advisor '" + name +
											"' with dependency on currently created bean: " + ex.getMessage());
								}
								// Ignore: indicates a reference back to the bean we're trying to advise.
								// We want to find advisors other than the currently created bean itself.
								continue;
							}
						}
						throw ex;
					}
				}
			}
		}
		return advisors;
	}

当上面执行完成后我们的用于实现事务的增强、切入点抽象出来的对象DefaultBeanFactoryPointcutAdvisor和BeanFactoryTransactionAttributeSourceAdvisor实例化

2.查找到所有事务抽象出来的advisor后,便需要去匹配符合当前被代理对象的advisor;

/**
	 * 确定适用于给定class的{@code candidateAdvisors}的子列表advisors
	 * @param candidateAdvisors the Advisors to evaluate
	 * @param clazz the target class
	 * @return sublist of Advisors that can apply to an object of the given class
	 * (may be the incoming List as-is)
	 */
	public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
		if (candidateAdvisors.isEmpty()) {
			return candidateAdvisors;
		}
		List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
		for (Advisor candidate : candidateAdvisors) {
			//判断class是否符合IntroductionAdvisor的增强
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
				eligibleAdvisors.add(candidate);
			}
		}
		//是否包含intructions,就是那个给代理类动态添加方法的
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		for (Advisor candidate : candidateAdvisors) {
			if (candidate instanceof IntroductionAdvisor) {
				// already processed
				continue;
			}
			//实现事务增强的BeanFactoryTransactionAttributeSourceAdvisor和DefaultBeanFactoryPointcutAdvisor
			//最终会通过该方法匹配 切入点
			if (canApply(candidate, clazz, hasIntroductions)) {
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}
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 {
			// It doesn't have a pointcut so we assume it applies.
			return true;
		}
	}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
		//class不匹配直接退出
		Assert.notNull(pc, "Pointcut must not be null");
		if (!pc.getClassFilter().matches(targetClass)) {
			return false;
		}
		//获取methodMatcher
		MethodMatcher methodMatcher = pc.getMethodMatcher();
		//为true直接返回true
		if (methodMatcher == MethodMatcher.TRUE) {
			// No need to iterate the methods if we're matching any method anyway...
			return true;
		}
		//向上造型为IntroductionAwareMethodMatcher
		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}
		//获取targetClass的所有classes包括父类
		Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
		classes.add(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;
	}

我们通过tx:advice声明的事务,和普通的aop:advisor一样,最终会通过类似<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>,根据advisor的pointcut属性确定出匹配beanclass适用的advisor。

而通过注解实现事务,其匹配pointcut有所不同,我们可以先看下BeanFactoryTransactionAttributeSourceAdvisor的pointcut属性是怎么样的

private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
		@Override
		protected TransactionAttributeSource getTransactionAttributeSource() {
			return transactionAttributeSource;
		}
	};

所以最后判断该advisor是否适用于当前beanclass最终实现在TransactionAttributeSourcePointcut.matches方法

@Override
	public boolean matches(Method method, Class<?> targetClass) {
		if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
			return false;
		}
		//根据前文分析我们知道他的类型为AnnotationTransactionAttributeSource
		TransactionAttributeSource tas = getTransactionAttributeSource();
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}

3.AnnotationTransactionAttributeSource.getTransactionAttribute方法

/**
	 * 确定此方法调用的事务属性
	 * <p>如果未找到方法属性,则默认为类的事务属性.
	 * @param method the method for the current invocation (never {@code null})
	 * @param targetClass the target class for this invocation (may be {@code null})
	 * @return a TransactionAttribute for this method, or {@code null} if the method
	 * is not transactional
	 */
	@Override
	public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
		//object的method方法比如(equals clone等等),直接返回Null
		if (method.getDeclaringClass() == Object.class) {
			return null;
		}

		// First, see if we have a cached value.
		// 我们先从缓存看看有没有
		// MethodClassKey
		Object cacheKey = getCacheKey(method, targetClass);
		//缓存的TransactionAtrribute
		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.
			//值将是规范值,表示没有事务属性或实际事务属性。返回null
			if (cached == NULL_TRANSACTION_ATTRIBUTE) {
				return null;
			}
			else {
				//返回缓存的TransactionAttribute
				return cached;
			}
		}
		else {
			// We need to work it out.
			// 获取txAttr属性好伐!
			TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
			// 为null 放一个NULL_TRANSACTION_ATTRIBUTE
			if (txAttr == null) {
				this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
			}
			else {
				//如果该targetClass的method方法有TransactionAttribute属性
				//设置descriptor属性,不是我们关注的重点
				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;
		}
	}

真正获取TransationAttribute属性的方法在computeTransactionAttribute(method, targetClass)

/**
	 * 与{@link #getTransactionAttribute}相同的签名,但不缓存结果.
	 * {@link #getTransactionAttribute}实际上是此方法的缓存装饰器.
	 * <p>As of 4.1.8, this method can be overridden.
	 * @since 4.1.8
	 * @see #getTransactionAttribute
	 */
	protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
		// 仅仅允许解析public方法的@Transaction 并且现在这个方法不是public;直接返回Null
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}

		// Ignore CGLIB subclasses - introspect the actual user class.
		// 返回用户实际的类
		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.
		// 该方法可能是接口上的,我们需要获取实现类中的方法
		Method specificMethod = ClassUtils.getMostSpecificMethod(method, userClass);
		// If we are dealing with method with generic parameters, find the original method.
		// 如果我们使用泛型参数处理方法,请找到原始方法
		specificMethod = BridgeMethodResolver.findBridgedMethod(specificMethod);

		// 首先查找target class 的method是否有txAttr
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) {
			return txAttr;
		}

		// Second try is the transaction attribute on the target class.

		// 然后 尝试在target class上查找txAttr
		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.

			// 退回到原始的class中查找
			txAttr = findTransactionAttribute(method.getDeclaringClass());
			if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
				return txAttr;
			}
		}

		return null;
	}

我们根据方法可以看出实现查找@Transaction注解的属性的策略为:特定的目标方法>目标类>接口方法>声明类或者接口;依次查找直到找到返回。

4.findTransactionAttribute方法委托给了子类实现;AnnotationTransactionAttributeSource.determineTransactionAttribute

/**
	 * 确定给定方法或类的事务属性.
	 * <p>此实现委托配置
	 * {@link TransactionAnnotationParser TransactionAnnotationParsers}
	 * 用于将已知注释解析为Spring的元数据属性类.
	 * 如果它不是事务性的,则返回{@code null}.
	 * <p>可以重写以支持带有事务元数据的自定义注释
	 * @param element the annotated method or class
	 * @return the configured transaction attribute, or {@code null} if none was found
	 */
	protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
		if (element.getAnnotations().length > 0) {
			for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
				//委托解析工作给SpringTransactionAnnotationParser或者JtaTransactionAnnotationParser
				//或者Ejb3TransactionAnnotationParser,这里我们只关心SpringTransactionAnnotationParser
				TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
				if (attr != null) {
					return attr;
				}
			}
		}
		return null;
	}

Spring给我们提供了三种annotationParsers;分别用于读取Spring的JDK 1.5+ {@link Transactional}注释,并向Spring的事务基础结构公开相应的事务属性 还支持JTA 1.2的{@link javax.transaction.Transactional}和EJB3的{@link javax.ejb.TransactionAttribute}注释(如果存在). 此类还可以作为自定义TransactionAttributeSource的基类,或通过{@link TransactionAnnotationParser}策略进行自定义.

5.SpringTransactionAnnotationParser.parseTransactionAnnotation

@Override
	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
		//提取@Transacation注解属性,并返回一个RuleBasedTransactionAttribute对象
		AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(
				element, Transactional.class);
		if (attributes != null) {
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}


	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<RollbackRuleAttribute>();
		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;
	}

上面的方法实现了对应类或者方法的事务属性解析。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值