真香警告!学习Spring事务源码解析看这一篇就够了

注入事务管理器【JDBC】

//注入数据源,这里使用的是阿里的Druid,这里只是简单的配置
@Bean
   public DruidDataSource dataSource(){
       DruidDataSource dataSource = new DruidDataSource();
       dataSource.setUsername("******");
       dataSource.setPassword("*****");
       dataSource.setUrl("******");
       dataSource.setInitialSize(10);
       dataSource.setMaxActive(20);
       dataSource.setMaxIdle(100000);
       return dataSource;
   }

//注入事务管理器
@Bean
   public PlatformTransactionManager transactionManager(DataSource dataSource){
       DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager(dataSource);
       return dataSourceTransactionManager;
   }
@Configuration
@ComponentScan(basePackages = {"cn.tedu.demo.*"})
@EnableTransactionManagement
public class MainConfig{}

源码解析事务

必知的知识和类

PlatformTransactionManager

TransactionDefinition

@EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

TransactionManagementConfigurationSelector

String[] selectImports(AnnotationMetadata importingClassMetadata);
@Override
protected String[] selectImports(AdviceMode adviceMode) {
	switch (adviceMode) {
		case PROXY:
			return new String[] {AutoProxyRegistrar.class.getName(),
					ProxyTransactionManagementConfiguration.class.getName()};
		case ASPECTJ:
			return new String[] {determineTransactionAspectClass()};
		default:
			return null;
	}
}

private String determineTransactionAspectClass(){
	return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
			TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
			TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
}

AutoProxyRegistrar

//importingClassMetadata:其中封装了配置类的所有注解
//registry:用于注入BeanDefintion
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry){
       //标记
	boolean candidateFound = false;
   	//获取所有的注解类型
	Set annoTypes = importingClassMetadata.getAnnotationTypes();
       //遍历注解
	for (String annoType : annoTypes) {
           //获取指定注解的全部属性的值
		AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
		if (candidate == null) {
			continue;
		}
           //获取对应的mode和proxyTargetClass属性的值
		Object mode = candidate.get("mode");
		Object proxyTargetClass = candidate.get("proxyTargetClass");
           //如果这些值都存在,那么可以判定配置类上标注了`@EnableTransactionManagement`这个注解
		if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&	
				Boolean.class == proxyTargetClass.getClass()) {
               //标记设置为true
			candidateFound = true;
               //根据mode的值,注入不同的APC
			if (mode == AdviceMode.PROXY) {
				AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
				if ((Boolean) proxyTargetClass) {
					AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
					return;
				}
			}
		}
	}
	if (!candidateFound && logger.isInfoEnabled()) {
		String name = getClass().getSimpleName();
		logger.info(String.format("%s was imported but no annotations were found " +
				"having both 'mode' and 'proxyTargetClass' attributes of type " +
				"AdviceMode and boolean respectively. This means that auto proxy " +
				"creator registration and configuration may not have occurred as " +
				"intended, and components may not be proxied as expected. Check to " +
				"ensure that %s has been @Import'ed on the same class where these " +
				"annotations are declared; otherwise remove the import of %s " +
				"altogether.", name, name, name));
	}
}
//cls是InfrastructureAdvisorAutoProxyCreator.class,APC的一种实现类
//注入的BeanName是org.springframework.aop.config.internalAutoProxyCreator
private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		//判断对应的APC是否已经注入了
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}
		
    	//没有注入,直接使用RootBeanDefinition注入,BeanName是org.springframework.aop.config.internalAutoProxyCreator
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry); :强制使用子类代理【cglib代理】,实际作用的源码如下:

public static void forceAutoProxyCreatorToUseClassProxying(BeanDefinitionRegistry registry){
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition definition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			definition.getPropertyValues().add("proxyTargetClass", Boolean.TRUE);
		}
	}

总结

ProxyTransactionManagementConfiguration

//ProxyTransactionManagementConfiguration配置类
@Configuration
public class ProxyTransactionManagementConfigurationextends AbstractTransactionManagementConfiguration{}

//AbstractTransactionManagementConfiguration
@Configuration
public abstract class AbstractTransactionManagementConfigurationimplements ImportAware{}
@Override
public void setImportMetadata(AnnotationMetadata importMetadata){
       //获取@EnableTransactionMangement的属性值赋值给enableTx
	this.enableTx = AnnotationAttributes.fromMap(
			importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName(), false));
       //如果为null,抛出异常
	if (this.enableTx == null) {
		throw new IllegalArgumentException(
				"@EnableTransactionManagement is not present on importing class " + importMetadata.getClassName());
	}
}

ImportAware

@Configuration
@ComponentScan(basePackages = {"cn.tedu.demo.*"})
@EnableTransactionManagement
@Import(value = {DruidConfig.class})
public class MainConfig{}


@Configuration
public class DruidConfigimplements ImportAware{
    @Override
    public void setImportMetadata(AnnotationMetadata importMetadata){
        System.out.println(importMetadata);
    }
}

InfrastructureAdvisorAutoProxyCreator【@EnableTransactionManagement导入】

真香警告!学习Spring事务源码解析看这一篇就够了

1)在org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary方法中是创建代理对象的主要方法,不过在这之前需要获取所有适用当前Bean的所有增强器(Advisor),调用的是Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);这个方法
	1.1) 进入org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean方法,调用的是List advisors = findEligibleAdvisors(beanClass, beanName)这段代码,获取可用的增强器
	1.2) 进入,实际调用的是List eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName)这段代码,获取能够作用在beanClass的增强器
	1.3)进入,实际调用的是AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass)这段代码
	1.4)一路跟进,最终到了org.springframework.aop.support.AopUtils#canApply(org.springframework.aop.Pointcut, ava.lang.Class<?>, boolean),主要的逻辑开始了
		1.4.1) 最重要的代码便是循环获取的接口,获取其中的方法,调用methodMatcher.matches(method, 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;
				}
			}
		}
		1.4.2)跟进,进入了org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#computeTransactionAttribute方法,主要的逻辑就是先判断当前Bean的所有方法是否有@Transactional注解,之后判断该类头上是否有@Transactional注解
		1.4.3)最重要的解析是否存在@Transactional注解的方法就是org.springframework.transaction.annotation.SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement),其中的逻辑如下:

		public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
		//获取注解@Transactional中的属性值
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
		//如果属性值不为空,表示该类获取方法上标注了@Transactional注解
		if (attributes != null) {
			//解析注解的属性值,封装在TransactionAttribute中返回
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}
	//解析注解的属性值,将其封装在TransactionAttribute中
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 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;
	}

SpringTransactionAnnotationParser

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element){
    	//获取注解中的所有属性值
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
		if (attributes != null) {
            //如果属性不为空,调用parseTransactionAnnotation方法封装
			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 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;
	}

AnnotationTransactionAttributeSource【@EnableTransactionManagement导入】

AnnotationTransactionAttributeSource【@EnableTransactionManagement导入】

//method:指定的方法,targetClass指定的类
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass){
    	//如果是Object,直接返回null
		if (method.getDeclaringClass() == Object.class) {
			return null;
		}

		// 第一步先直接从缓存中取值,如果存在,直接返回即可
		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 {
			//如果缓存中没有,那么需要调用computeTransactionAttribute方法去ioc中解析
			TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
			//将取出的值存入缓存中,下次再取就不需要解析了,直接取值即可
			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.isTraceEnabled()) {
					logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
				}
				this.attributeCache.put(cacheKey, txAttr);
			}
			return txAttr;
		}
	}


/**********************************computeTransactionAttribute****************/
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass){
		//如果方法不是public类型的,直接返回null
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
			return null;
		}

		//如果method方法是在接口中定义的方法,那么获取接口实现类的方法。
		Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

		// 尝试获取目标方法上标注的@Transactional注解的属性【因为这个注解可以标注在方法和类上】
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) {
			return 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.
			txAttr = findTransactionAttribute(method.getDeclaringClass());
			if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
				return txAttr;
			}
		}

		return null;
	}
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element){
    	//遍历可用的事务注解解析器->this.annotationParsers
		for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
            //调用解析的方法,进行解析
			TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
			if (attr != null) {
				return attr;
			}
		}
		return null;
	}

/***org.springframework.transaction.annotation.SpringTransactionAnnotationParser#parseTransactionAnnotation(java.lang.reflect.AnnotatedElement)****/
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element){
    	//直接获取元素上@Transactional注解的属性,如果获取都了,将其解析成TransactionAttribute对象返回即可
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
		if (attributes != null) {
			return parseTransactionAnnotation(attributes);
		}
    	//不存在该注解,那么直接返回null
		else {
			return null;
		}

BeanFactoryTransactionAttributeSourceAdvisor【@EnableTransactionManagement导入】

TransactionInterceptor【重要】

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {

		// If the transaction attribute is null, the method is non-transactional.
		TransactionAttributeSource tas = getTransactionAttributeSource();
		final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

		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;
		}

调用标注@Transactional方法

前提

解析