Spring transaction source code (3)

Spring transaction source code (3)

1. At the beginning, my friends who have seen the Aop source code in front of me should be very familiar with the entire process of the transaction.
Insert picture description here
2. Source code analysis. This chapter only analyzes the source code of the enhancer that meets the conditions.findAdvisorsThatCanApply, For finding the source code of the enhancerfindCandidateAdvisorsPlease refer to the blog https://blog.csdn.net/mlplds/article/details/103145409

protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    
    

		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
    
    
		//真正的去候选的增强器中找到当前能用的增强器
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
    
    
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}
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) {
    
    
		//判断增强器是不是实现了IntroductionAdvisor 很明显没实现该接口(看继承图)
			if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
    
    
				eligibleAdvisors.add(candidate);
			}
		}
		boolean hasIntroductions = !eligibleAdvisors.isEmpty();
		for (Advisor candidate : candidateAdvisors) {
    
    
			if (candidate instanceof IntroductionAdvisor) {
    
    
				// already processed
				continue;
			}
			//正在找出能用的增强器
			if (canApply(candidate, clazz, hasIntroductions)) {
    
    
				eligibleAdvisors.add(candidate);
			}
		}
		return eligibleAdvisors;
	}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
    
    
		//根据类的继承图 发现 BeanFactoryTransactionAttributeSourceAdvisor没实现IntroductionAdvisor接口
		if (advisor instanceof IntroductionAdvisor) {
    
    
			return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
		}
		//BeanFactoryTransactionAttributeSourceAdvisor实现了PointcutAdvisor接口
		else if (advisor instanceof PointcutAdvisor) {
    
    
		//强制转换为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) {
    
    
		Assert.notNull(pc, "Pointcut must not be null");
		if (!pc.getClassFilter().matches(targetClass)) {
    
    
			return false;
		}
			/** 
			* 获取切点中的方法匹配器 TransactionAttributeSourcePointcut 
			* * 该切点在创建BeanFactoryTransactionAttributeSourceAdvisor的时候 创建了切点TransactionAttributeSourcePointcut 
			* */
		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类型)
		* */
		IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
		if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
    
    
			introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
		}
		//获取当前类的实现接口类型
		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) {
    
    
			//正在进行匹配的是methodMatcher.matches(method, targetClass)这个逻辑
				if ((introductionAwareMethodMatcher != null &&
						introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
						methodMatcher.matches(method, targetClass)) {
    
    
					return true;
				}
			}
		}

		return false;
	}

TransactionAttributeSourcePointcut

public boolean matches(Method method, Class<?> targetClass) {
    
    
		if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {
    
    
			return false;
		}
		//获取我们的事物源对象(在ProxyTransactionManagementConfiguration配置类配置的这里获取) 
		//在创建时BeanFactoryTransactionAttributeSourceAdvisor时创建TransactionAttributeSourcePointcut时复写了getTransactionAttributeSource
		TransactionAttributeSource tas = getTransactionAttributeSource();
		//从事物源对象中获取事物属性
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}
public TransactionAttribute getTransactionAttribute(Method method, Class<?> targetClass) {
    
    
		if (method.getDeclaringClass() == Object.class) {
    
    
			return null;
		}

		// First, see if we have a cached value.
		//通过目标类和目标类的接口方法 拼接缓存key
		Object cacheKey = getCacheKey(method, targetClass);
		//去缓存中获取
		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 {
    
    
				return cached;
			}
		}
		else {
    
    
			// We need to work it out.
			//计算事物属性
			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);
				}
				//加入到缓存
				this.attributeCache.put(cacheKey, txAttr);
			}
			return txAttr;
		}
	}
protected TransactionAttribute computeTransactionAttribute(Method method, Class<?> targetClass) {
    
    
		// Don't allow no-public methods as required.
		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为我们实现类方法 * */
		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.
		// 找我们【实现类】中的【方法】上的事物属性
		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;
			}
		}

		return null;
	}
@Override
	protected TransactionAttribute findTransactionAttribute(Method method) {
    
    
		return determineTransactionAttribute(method);
	}
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
    
    
		//获取方法上的注解
		if (element.getAnnotations().length > 0) {
    
    
		//事物注解解析器
			for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
    
    
			//解析我们的注解
				TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
				if (attr != null) {
    
    
					return attr;
				}
			}
		}
		return null;
	}

SpringTransactionAnnotationParser

@Override
	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
    
    
	//解析@Transactional属性对象(AnnotationAttributes extends LinkedHashMap<String, Object>)
		AnnotationAttributes attributes = AnnotatedElementUtils.getMergedAnnotationAttributes(
				element, Transactional.class);
		if (attributes != null) {
    
    
		//真正的解析@Transactional属性(包装一下)
			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;
	}

Find a good enhancer of this kind. Start to create a dynamic agent. I have already analyzed it before. I will not do a detailed analysis this time.
Insert picture description here
3. This chapter is here. The next chapter will analyze the call of the dynamic agent.

Guess you like

Origin blog.csdn.net/mlplds/article/details/103339336