AoP应用之事务(2) 事务的方法及代理类的创建

189 阅读1分钟

既然事务是用AoP实现的,自然也会经历一个完整的AoP过程。

切面方法查找

AnnotationAwareAspectJAutoProxyCreator->findCandidateAdvisors():
    // Spring中的切面方法,如事务的切面方法
    List<Advisor> advisors = super.findCandidateAdvisors();
AbstractAdvisorAutoProxyCreator->findCandidateAdvisors():
    return this.advisorRetrievalHelper.findAdvisorBeans();
BeanFactoryAdvisorRetrievalHelper->findAdvisorBeans():
    // 获取IoC容器中所有beanName,查找实现了Advisor接口的类,实例化之后返回
    advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                this.beanFactory, Advisor.class, true, false);

这里返回的beanName为org.springframework.transaction.config.internalTransactionAdvisor,对应的实体类BeanFactoryTransactionAttributeSourceAdvisor也确实实现了Advisor接口,是在ProxyTransactionManagementConfiguration类中导入的,如图。

切面表达式

事务切面类跳过了切面表达式的验证,只判断方法是否符合切面表达式

TransactionAttributeSourcePointcut->matches():
    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);
AbstractFallbackTransactionAttributeSource->getTransactionAttribute():
    if (method.getDeclaringClass() == Object.class) {
        return null;
    }
    TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
    // 放入缓存,这样下次判断的时候就知道这个方法是否符合切面表达式了
    ......
AbstractFallbackTransactionAttributeSource->computeTransactionAttribute():
    if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
        return null;
    }
    // 先看方法是否含有@Transactional注解
    TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
    if (txAttr != null) {
        return txAttr;
    }
    // 如果方法没有,看类是否含有@Transactional注解
    txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
    if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
        return txAttr;
    }
AnnotationTransactionAttributeSource->findTransactionAttribute():
    return determineTransactionAttribute(method);
AnnotationTransactionAttributeSource->determineTransactionAttribute():
    for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
        TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
        if (attr != null) {
            return attr;
        }
    }
SpringTransactionAnnotationParser->parseTransactionAnnotation():
    // 查找所给方法或类是否含有@Transactional注解,有的话,解析注解的值,封装成TransactionAttribute对象返回,否则返回空
    AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
                element, Transactional.class, false, false);
    if (attributes != null) {
        return parseTransactionAnnotation(attributes);
    }
    else {
        return null;
    }

根据代码可知,以下几种不符合切面表达式:

  1. 目标类是TransactionalProxyPlatformTransactionManagerPersistenceExceptionTranslator类及其子类
  2. 目标类是Object
  3. 目标方法不以public修饰
  4. 目标方法和目标类都没有@Transactional注解

看来,只要公共方法或类含有@Transactional注解,就满足切面表达式了

代理类的创建

参考SpringBoot AoP(4)代理类的创建与运行