Spring之事务注解@Transactional解析(一)

代码示例

@Configuration
@EnableTransactionManagement
public class DataSourceConfiguration {

	@Bean
	public BasicDataSource getBasicDataSource() {
		BasicDataSource dataSource = new BasicDataSource();
		dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
		dataSource.setUrl("jdbc:mysql://localhost:3306/my_test?useSSL=false&useUnicode=true&characterEncoding=UTF-8");
		dataSource.setUsername("root");
		dataSource.setPassword("123qwe..");
		return dataSource;
	}

	@Bean
	public DataSourceTransactionManager transactionManager(BasicDataSource dataSource) {
		return new DataSourceTransactionManager(dataSource);
	}

	@Bean
	public JdbcTemplate getJdbcTemplate(BasicDataSource dataSource) {
		return new JdbcTemplate(dataSource);
	}
}
public interface AccountService {
    void save() throws RuntimeException;
}
@Transactional
@Service
public class AccountServiceImpl implements AccountService {

	@Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void save() throws RuntimeException {
        System.out.println("==开始执行sql");
        jdbcTemplate.update("insert into account(balance) values (100)");
        System.out.println("==结束执行sql");

        System.out.println("==准备抛出异常");
        throw new RuntimeException("==手动抛出一个异常");
    }
}
public class MyTest {

	public static void main(String[] args) {
		ApplicationContext ctx = new AnnotationConfigApplicationContext("com.huang.sourcelearn.tx");
		AccountService studentService = ctx.getBean(AccountService.class);
		studentService.save();
	}
}

执行完后去数据库查看可以发现发生了回滚,数据并没有插入进去。

源码解析

@EnableTransactionManagement

@EnableTransactionManagement 是开启事务的注解

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

	boolean proxyTargetClass() default false;

	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;

}

这里通过 @Import 导入了一个类

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

	/**
	 * Returns {@link ProxyTransactionManagementConfiguration} or
	 * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
	 * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
	 * respectively.
	 */
	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		// 根据@EnableTransactionManagement注解上的mode属性决定要注册哪个bean,默认是proxy,
		// 所以这里会向容器注册AutoProxyRegistrar和ProxyTransactionManagementConfiguration两个bean
		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 和 ProxyTransactionManagementConfiguration 两个bean。

具体如何注册可以看该篇解析Spring扩展之@Import 和 ImportSelector 接口

AutoProxyRegistrar

public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	private final Log logger = LogFactory.getLog(getClass());

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
		// @EnableTransactionManagement所在类上的所有注解
		Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
		// 遍历每个注解
		for (String annType : annTypes) {
			// 注解上的所有属性
			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
			if (candidate == null) {
				continue;
			}
			// 需要注解上有mode属性和proxyTargetClass属性才会创建自动代理创建者
			Object mode = candidate.get("mode");
			Object proxyTargetClass = candidate.get("proxyTargetClass");
			if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
					Boolean.class == proxyTargetClass.getClass()) {
				candidateFound = true;
				// mode=proxy 则注册一个自动代理创建者InfrastructureAdvisorAutoProxyCreator来创建代理,
                // 默认是proxy
				if (mode == AdviceMode.PROXY) {
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
					// 默认是false
					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));
		}
	}

}

该类实现了 ImportBeanDefinitionRegistrar 接口,所以会注册BeanDefinition。 根据将mode和proxyTargetClass属性设置为正确值的@Enable*注解,注册一个自动代理创建者。 主要是注册 InfrastructureAdvisorAutoProxyCreator 这个bean。

ProxyTransactionManagementConfiguration

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	/**
	 * 创建一个用于事务增强的Advisor,通过查找是否有@Transactional注解来匹配
	 */
	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		// 设置事务属性源,用在切点中
        advisor.setTransactionAttributeSource(transactionAttributeSource());
		// 设置advice
        advisor.setAdvice(transactionInterceptor());
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
		return new AnnotationTransactionAttributeSource();
	}

	/**
	 * 事务增强逻辑advice
	 */
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionInterceptor transactionInterceptor() {
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource());
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}

该类主要是向容器注册基于代理的注解驱动的事务管理所需的 Spring 基础 bean,注册了3个bean。

这里贴下 BeanFactoryTransactionAttributeSourceAdvisor 这个类

public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

    // Advice在父类AbstractBeanFactoryPointcutAdvisor中
    
    // AnnotationTransactionAttributeSource
	@Nullable
	private TransactionAttributeSource transactionAttributeSource;

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


	/**
	 * Set the transaction attribute source which is used to find transaction
	 * attributes. This should usually be identical to the source reference
	 * set on the transaction interceptor itself.
	 * @see TransactionInterceptor#setTransactionAttributeSource
	 */
	public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
		this.transactionAttributeSource = transactionAttributeSource;
	}

	/**
	 * Set the {@link ClassFilter} to use for this pointcut.
	 * Default is {@link ClassFilter#TRUE}.
	 */
	public void setClassFilter(ClassFilter classFilter) {
		this.pointcut.setClassFilter(classFilter);
	}

	@Override
	public Pointcut getPointcut() {
		return this.pointcut;
	}

}

上面讲到在 AutoProxyRegistrar 类中注册了 InfrastructureAdvisorAutoProxyCreator 这个bean,那就来看看这个类

InfrastructureAdvisorAutoProxyCreator

public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

	@Nullable
	private ConfigurableListableBeanFactory beanFactory;


	@Override
	protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
		super.initBeanFactory(beanFactory);
		this.beanFactory = beanFactory;
	}

	@Override
	protected boolean isEligibleAdvisorBean(String beanName) {
		return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
				this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
	}

}

它的继承关系如下:
在这里插入图片描述
可以看到该类间接实现了InstantiationAwareBeanPostProcessor 接口,也就是说在Spring中,所有bean实例化时都会调用该类的 postProcessAfterInstantiation方法,其实现是在父类AbstractAutoProxyCreator类中实现。

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        // 为给定的 bean 类和 bean 名称构建缓存键,如果是普通类,缓存键就是beanName,如果是FactoryBean,缓存键是 & + beanName
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        // 如果缓存中cacheKey对应的缓存就是该bean,就表示已经尝试过创建代理对象了,这里无需再执行,直接返回bean
        // (如果增强了那最终就不是使用这个bean了,外层会使用代理对象替换该bean)
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    // 从缓存中获知该bean不需要生成代理
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    // 如果是基础设施类(Pointcut、Advice、Advisor 等接口的实现类),或是应该跳过的类,
    // 则不应该生成代理,此时直接返回 bean
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

    // 获取可应用于该bean的advisor增强器
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
        // 表示该bean需要生成代理
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        // 创建代理对象
        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;
}

对于事务来说,唯一的advisor就是上面一开始注册的BeanFactoryTransactionAttributeSourceAdvisor,所以getAdvicesAndAdvisorsForBean方法就是判断当前的bean是否与BeanFactoryTransactionAttributeSourceAdvisor匹配,简单说就是bean上是否有配置事务。

@Override
@Nullable
protected Object[] getAdvicesAndAdvisorsForBean(
    Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
	// 获取可应用于该bean的advisor增强器
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    // 空表示没有匹配的增强,无需生成代理
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    // 获取全部advisor
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    // 筛选出匹配该bean的advisor,通过 ClassFilter 和 MethodMatcher对目标类和方法进行匹配
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    // 对eligibleAdvisors进行了扩展,添加了ExposeInvocationInterceptor拦截器,
    // 用来传递MethodInvocation的
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        // 排序
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

先获取所有的advisor

protected List<Advisor> findCandidateAdvisors() {
    Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
    return this.advisorRetrievalHelper.findAdvisorBeans();
}
public List<Advisor> findAdvisorBeans() {
    // 缓存列表,一开始是空的
    String[] advisorNames = this.cachedAdvisorBeanNames;
    if (advisorNames == null) {
        // 从容器中获取advisor类型的bean名称,
        // 在这里就是BeanFactoryTransactionAttributeSourceAdvisor
        advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
            this.beanFactory, Advisor.class, true, false);
        this.cachedAdvisorBeanNames = advisorNames;
    }
    if (advisorNames.length == 0) {
        return new ArrayList<>();
    }

    List<Advisor> advisors = new ArrayList<>();
    for (String name : advisorNames) {
        if (isEligibleBean(name)) {
            if (this.beanFactory.isCurrentlyInCreation(name)) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Skipping currently created advisor '" + name + "'");
                }
            }
            else {
                try {
                    // 从容器获取advisor,
                    // 在这里就是BeanFactoryTransactionAttributeSourceAdvisor
                    advisors.add(this.beanFactory.getBean(name, Advisor.class));
                }
                catch (BeanCreationException ex) {
                    Throwable rootCause = ex.getMostSpecificCause();
                    if (rootCause instanceof BeanCurrentlyInCreationException) {
                        BeanCreationException bce = (BeanCreationException) rootCause;
                        String bceBeanName = bce.getBeanName();
                        if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
                            if (logger.isTraceEnabled()) {
                                logger.trace("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;
}

然后从中筛选出可以应用当前bean的advisor

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

    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        // 使用aop工具类类筛选
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    }
    finally {
        ProxyCreationContext.setCurrentProxiedBeanName(null);
    }
}
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
    }
    // 用来保存筛选出来的advisor
    List<Advisor> eligibleAdvisors = new ArrayList<>();
    // 我们一般很少用IntroductionAdvisor,处理引介增强的
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
            eligibleAdvisors.add(candidate);
        }
    }
    boolean hasIntroductions = !eligibleAdvisors.isEmpty();
    // 遍历每个advisor
    for (Advisor candidate : candidateAdvisors) {
        if (candidate instanceof IntroductionAdvisor) {
            // 因为上面已经处理过了,所以这里跳过
            continue;
        }
        // 重点是这里,如果匹配上,就加入到eligibleAdvisors,最后返回
        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;
        // 这里getPointcut返回TransactionAttributeSourcePointcut类型的切点
        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");
    // 在类层面进行粗筛,
    // TransactionAttributeSourcePointcut中的类过滤器时ClassFilter.TRUE,
    // 所以这里对所有类都匹配通过
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    }

    // 对每个方法进行匹配,只要有一个匹配,就返回true,
    // TransactionAttributeSourcePointcut的方法匹配器就是它本身
    MethodMatcher methodMatcher = pc.getMethodMatcher();
    if (methodMatcher == MethodMatcher.TRUE) {
        // 任何方法都匹配
        return true;
    }

    // IntroductionAwareMethodMatcher是MethodMatcher的一种特殊类型,
    // 这里不匹配,会跳过
    IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    }

    Set<Class<?>> classes = new LinkedHashSet<>();
    if (!Proxy.isProxyClass(targetClass)) {
        // 向classes添加目标类Class
        classes.add(ClassUtils.getUserClass(targetClass));
    }
    // 添加实现的接口
    classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

    for (Class<?> clazz : classes) {
        // 反射获取类(接口)中的所有方法
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
        // 遍历每个方法,校验是否与表达式匹配,
        // 这里是调用TransactionAttributeSourcePointcut类的matches方法
        // 只要有找到一个就返回true了,如果其它方法也有自己的事务属性这里不会解析,
        // 后面调方法时会再解析
        for (Method method : methods) {
            if (introductionAwareMethodMatcher != null ?
                introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                methodMatcher.matches(method, targetClass)) {
                return true;
            }
        }
    }

    return false;
}

这里会调用 TransactionAttributeSourcePointcut 类的matches方法进行匹配

@Override
public boolean matches(Method method, Class<?> targetClass) {
    if (TransactionalProxy.class.isAssignableFrom(targetClass) ||
        PlatformTransactionManager.class.isAssignableFrom(targetClass) ||
        PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
        return false;
    }
    TransactionAttributeSource tas = getTransactionAttributeSource();
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

这里的TransactionAttributeSource就是一开始注册的AnnotationTransactionAttributeSource,在BeanFactoryTransactionAttributeSourceAdvisor创建的时候就设置进去了
在这里插入图片描述

tas肯定是非空的,所以要根据tas.getTransactionAttribute(method, targetClass) != null)来判断是否匹配。
getTransactionAttribute逻辑在父类AbstractFallbackTransactionAttributeSource中

@Override
@Nullable
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    if (method.getDeclaringClass() == Object.class) {
        return null;
    }

    // 首先看下该方法的事务属性是否已经缓存了
    Object cacheKey = getCacheKey(method, targetClass);
    TransactionAttribute cached = this.attributeCache.get(cacheKey);
    if (cached != null) {
        // 当方法对应的缓存的事务属性值是NULL_TRANSACTION_ATTRIBUTE,
        // 表示该方法没有对应的事务属性值,不需要再解析了
        if (cached == NULL_TRANSACTION_ATTRIBUTE) {
            return null;
        }
        else {
            return cached;
        }
    }
    else {
        // 缓存是空的就需要去解析事务属性出来
        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;
    }
}

会先看下缓存有没有,没有的话就解析一次后放进缓存中

@Nullable
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
    // Don't allow no-public methods as required.
    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
        return null;
    }

    // 获取目标真实类上的方法,因为targetClass可能已经是一个代理类,那事务属性肯定要先看真实类上的方法的事务,
    // 或者这个方法是接口上的方法,需要取到目标类上的方法。(一般情况下method和specificMethod是同一个对象)
    Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

    // 先尝试在该方法上查找是否有@Transactional注解,有就将注解信息封装为TransactionAttribute返回
    // 先在类的方法上找,没有再到接口的方法上找
    TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
    if (txAttr != null) {
        return txAttr;
    }

    // 方法上没找到就再尝试从类上找是否有@Transactional注解,有就将注解信息封装为TransactionAttribute返回
    // 先在类上找,没有再到接口上找
    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;
}

先尝试在目标类的方法上查找是否有@Transactional注解,有就将注解信息封装为TransactionAttribute返回

@Override
@Nullable
protected TransactionAttribute findTransactionAttribute(Method method) {
    return determineTransactionAttribute(method);
}

@Nullable
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
    // 委托给事务属性解析器解析
    // 默认有一个SpringTransactionAnnotationParser,用来解析spring的@Transactional注解
    for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
        TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
        if (attr != null) {
            return attr;
        }
    }
    return null;
}

如果目标类方法上没找到事务属性,就到类上面去找

@Override
@Nullable
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
    return determineTransactionAttribute(clazz);
}

@Nullable
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
    // 委托给事务属性解析器解析
    // 默认有一个SpringTransactionAnnotationParser,用来解析spring的@Transactional注解
    for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
        TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
        if (attr != null) {
            return attr;
        }
    }
    return null;
}

SpringTransactionAnnotationParser

该类是用来解析spring的@Transactional注解

public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {

	@Override
	@Nullable
	public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
        // 获取element(类或方法)上的@Transactional注解
		AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
				element, Transactional.class, false, false);
        // 如果找到了该注解,就解析该注解,得到事务属性
		if (attributes != null) {
			return parseTransactionAnnotation(attributes);
		}
		else {
			return null;
		}
	}

	public TransactionAttribute parseTransactionAnnotation(Transactional ann) {
		return parseTransactionAnnotation(AnnotationUtils.getAnnotationAttributes(ann, false, false));
	}

	protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
		// 构建一个RuleBasedTransactionAttribute
        RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();

        // 解析@Transactional注解里面的属性,设置到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;
	}


	@Override
	public boolean equals(Object other) {
		return (this == other || other instanceof SpringTransactionAnnotationParser);
	}

	@Override
	public int hashCode() {
		return SpringTransactionAnnotationParser.class.hashCode();
	}

}

最后返回一个事务属性回去,回到TransactionAttributeSourcePointcut类的matches方法中

@Override
public boolean matches(Method method, Class<?> targetClass) {
    if (TransactionalProxy.class.isAssignableFrom(targetClass) ||
        PlatformTransactionManager.class.isAssignableFrom(targetClass) ||
        PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
        return false;
    }
    TransactionAttributeSource tas = getTransactionAttributeSource();
    return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

如果有事务属性,则tas.getTransactionAttribute(method, targetClass) != null成立。这样就说明BeanFactoryTransactionAttributeSourceAdvisor可以匹配到当前的bean,后面就需要创建代理对象了。创建过程在aop一篇中已经解析过了,这里就不再重复解析。

至此,我们就完成了事务注解的解析。总结下就是找出某个增强器是否适合于对应的类,而是否匹配的关键则在于是否从指定的类或类中的方法中找到对应的事务属性,我们以AccountServiceImpl为例,已经在其中找到了事务属性,所以,它是与事务增强器匹配的,也就是它会被事务功能修饰。
当判断某个bean适用于事务增强时,也就是适用于增强器BeanFactoryTransactionAttributeSourceAdvisor。
BeanFactoryTransactionAttributeSourceAdvisor 作为 Advisor 的实现类,自然要遵从 Advisor 的处理方式,当代理被调用时会调用这个类的增强方法,也就是此bean的Advice,又因为在解析事务时我们把Transactionlnterceptor类的bean注人到了 BeanFactoryTransactionAttributeSourceAdvisor中,所以,在调用事务增强器增强的代理类时会首先执行Transactionlnterceptor进行增强,同时,也就是在Transactionlnterceptor类中的invoke方法中完成了整个事务的逻辑。

摘自《spring5 源码深度解析----- Spring事务 是怎么通过AOP实现的?(100%理解Spring事务)》

下一篇Spring之事务注解@Transactional解析(二)对 Transactionlnterceptor 的事务增强逻辑进行解析。

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值