SpringBoot之事务源码解析

1、InfrastructureAdvisorAutoProxyCreator

初始化bean过程中涉及的beanPostProcessor之InfrastructureAdvisorAutoProxyCreator作为服务启动过程中解析@Transaction注解注释的方法或者类。

通过调用其InfrastructureAdvisorAutoProxyCreator之After相关的初始化后置处理器。

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
	...
	// Create proxy if we have advice.
	// 如果当前类存在事务注解,则返回BeanFactoryTransactionAttributeSourceAdvisor集合,并创建当前类的代理类
	Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
	if (specificInterceptors != DO_NOT_PROXY) {//true
		this.advisedBeans.put(cacheKey, Boolean.TRUE);
		// 创建带有事务注解的当前类的cglib代理类
		Object proxy = createProxy(
				bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
		this.proxyTypes.put(cacheKey, proxy.getClass());
		return proxy;
	}

	this.advisedBeans.put(cacheKey, Boolean.FALSE);
	return bean;
}
  1. 如果当前类存在事务【当前类或者其方法存在注解@Transactional】,则返回核心类BeanFactoryTransactionAttributeSourceAdvisor集合。通过核心类BeanFactoryTransactionAttributeSourceAdvisor其父类advice属性之TransactionInterceptor创建当前类的Cglib代理类。
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	// #1.1
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	//#1.2
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

Eligible:有资格的; 合格的; 具备条件的。

  1. 获取处理事务的核心接口Advisor的子类BeanFactoryTransactionAttributeSourceAdvisor
  2. 通过步骤1获取当前类的切面顾问Advisor

1.1、核心类BeanFactoryTransactionAttributeSourceAdvisor

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
	
	// AbstractAdvisorAutoProxyCreator$BeanFactoryAdvisorRetrievalHelperAdapter表示AbstractAdvisorAutoProxyCreator的内部类
	private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;
	
	protected List<Advisor> findCandidateAdvisors() {
		//BeanFactoryAdvisorRetrievalHelperAdapter
		return this.advisorRetrievalHelper.findAdvisorBeans();
	}
	
	private class BeanFactoryAdvisorRetrievalHelperAdapter extends BeanFactoryAdvisorRetrievalHelper {

		public BeanFactoryAdvisorRetrievalHelperAdapter(ConfigurableListableBeanFactory beanFactory) {
			super(beanFactory);
		}

		@Override
		protected boolean isEligibleBean(String beanName) {
			return AbstractAdvisorAutoProxyCreator.this.isEligibleAdvisorBean(beanName);
		}
	}
}

1.1.1、BeanFactoryAdvisorRetrievalHelper

public List<Advisor> findAdvisorBeans() {
	// Determine list of advisor bean names, if not cached already.
	// cachedAdvisorBeanNames:org.springframework.transaction.config.internalTransactionAdvisor
	String[] advisorNames = this.cachedAdvisorBeanNames;
	...
	List<Advisor> advisors = new ArrayList<>();
	for (String name : advisorNames) {
		advisors.add(this.beanFactory.getBean(name, Advisor.class));
	}
	return advisors;
}
  1. 通过name之internalTransactionAdvisor获取事先初始化完毕的接口Advisor切面顾问的默认实现类BeanFactoryTransactionAttributeSourceAdvisor。
  2. BeanFactoryTransactionAttributeSourceAdvisor中父类属性advice为TransactionInterceptor

1.2、通过核心类解析当前事务类或者事务方法对应的类

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
	List<Advisor> eligibleAdvisors = new ArrayList<>();
	...
	for (Advisor candidate : candidateAdvisors) {//BeanFactoryTransactionAttributeSourceAdvisor
		...
		if (canApply(candidate, clazz, hasIntroductions)) {//判断利用当前切面顾问Advisor是否可以作用于当前类
			eligibleAdvisors.add(candidate);
		}
	}
	return eligibleAdvisors;
}
  1. 判断利用当前切面顾问Advisor是否可以作用于当前类,即当前类是否存在事务。
  2. 如果当前类或者当前类中某个方法存在@Transactional注解相关属性,则
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
	...
	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;
	}
}

判断当前类是否为接口Advisor的子类。

1.2.1、解析当前类所有方法

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
	....
	Set<Class<?>> classes = new LinkedHashSet<>();
	if (!Proxy.isProxyClass(targetClass)) {
		classes.add(ClassUtils.getUserClass(targetClass));
	}
	//获取当前类targetClass所有接口
	classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

	for (Class<?> clazz : classes) {
		Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
		for (Method method : methods) {
			// introductionAwareMethodMatcher 为null
			if (introductionAwareMethodMatcher != null ?
					introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
					methodMatcher.matches(method, targetClass)) {//matches返回TRUE
				return true;
			}
		}
	}
	return false;
}
  1. 遍历当前类及其接口所有方法。一旦当前类某个方法存在事务相关注解,则matches方法返回TRUE。
public boolean matches(Method method, Class<?> targetClass) {
    if (!TransactionalProxy.class.isAssignableFrom(targetClass) && 	
    					!PlatformTransactionManager.class.isAssignableFrom(targetClass) && 
    					!PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
        TransactionAttributeSource tas = this.getTransactionAttributeSource();
        //解析方法上transaction注解
        return tas == null || tas.getTransactionAttribute(method, targetClass) != null;
    } else {
        return false;
    }
}
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
	// First, see if we have a cached value.
	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 {
		// 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);
			...
			this.attributeCache.put(cacheKey, txAttr);
		}
		return txAttr;
	}
}
  1. 返回method上Transactional注解的相关字段属性。
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
	...
	// #1.2.2 解析当前类中某个方法method是否存在@Transactional注解相关属性
	TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
	if (txAttr != null) {//如果存在Transactional注解则直接返回
		return txAttr;
	}

	// Second try is the transaction attribute on the target class.
	txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
	if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
		return txAttr;
	}
	...
	return null;
}
  1. 事务方法、事务类都是public修饰的。
  2. 首先解析当前类中的方法是否存在注解。
  3. 如果步骤2不成立,则解析当前类是否存在注解。

1.2.2、解析Transactional注解SpringTransactionAnnotationParser

public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {
	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
		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<>();
		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;
	}
}

你可能感兴趣的:(SpringBoot,Spring,java,spring,boot,java,spring)