33.Spring事务源码之整体流程

文章详细分析了Spring中@Transactional注解的处理流程,包括如何通过AOP找到对应的事务管理器,如何查找和匹配符合条件的事务Advisor,以及如何在方法执行前后管理事务。核心是通过BeanFactoryTransactionAttributeSourceAdvisor和TransactionInterceptor来实现事务的开启、提交和回滚。
摘要由CSDN通过智能技术生成

highlight: arduino-light

整体流程

第一步是注入自定义的事务管理器。

第二步是注入事务相关组件。

0.注入PlatformTransactionManager
//默认的bean名称是 myPlatformTransactionManager
@Component()
public class MyPlatformTransactionManager implements PlatformTransactionManager {
    @Override
    public TransactionStatus getTransaction(TransactionDefinition definition) throws TransactionException {
        System.out.println("getTransaction");
        return new SimpleTransactionStatus();
    }
​
    @Override
    public void commit(TransactionStatus status) throws TransactionException {
        System.out.println("commit");
    }
​
    @Override
    public void rollback(TransactionStatus status) throws TransactionException {
        System.out.println("rollback");
    }
}
1.注入InfrastructureAdvisorAutoProxyCreator

主要的作用有2个:

1.参与获取候选advisor

在获取候选advisor时,让我们可以获取到BeanFactoryTransactionAttributeSourceAdvisor。

因为BeanFactoryTransactionAttributeSourceAdvisor的ROLE就是BeanDefinition.ROLE_INFRASTRUCTURE

InfrastructureAdvisorAutoProxyCreator获取候选ROLE的逻辑也是判断是否等于BeanDefinition.ROLE_INFRASTRUCTURE.

2.作为beanPostProcessor被注入,在生成代理对象时参与代理的过程!

@Override
    protected boolean isEligibleAdvisorBean(String beanName) {
        /****
    这个条件是寻找AVISOR的Role是 ROLE_INFRASTRUCTURE
    比如 BeanFactoryTransactionAttributeSourceAdvisor
    @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {}
         */
        return (this.beanFactory != null && 
                this.beanFactory
                    .containsBeanDefinition(beanName) &&
                //判断getRole() == BeanDefinition.ROLE_INFRASTRUCTURE
                this.beanFactory
                        .getBeanDefinition(beanName)
                            .getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
    }
2.注入BeanFactoryTransactionAttributeSourceAdvisor

注入BeanFactoryTransactionAttributeSourceAdvisor对应的bean实例,让我们在生成代理获取候选的advisor时可以获取到这个advsior。

注入的advisor有以下属性

//注入解析器
//可以调用getTransactionAttributeSource 获取解析器 
//解析方法上是否存在@Transaction注解
advisor.setTransactionAttributeSource(transactionAttributeSource());


//transactionInterceptor()返回1个transactionInterceptor
//transactionInterceptor里包含了事务管理器
//有2个用处:
//1.获取调用链时调用getInterceptorsAndDynamicInterceptionAdvice方法
//将BeanFactoryTransactionAttributeSourceAdvisor
//转换为transactionInterceptor
//因为在BeanFactoryTransactionAttributeSourceAdvisor的注入方法中已经设置了
//advisor.setAdvice(transactionInterceptor());

//2.执行代理类的invoke方法的时候会用上此处的transactionInterceptor中的事务管理器
//具体看transactionInteceptor的invoke方法
advisor.setAdvice(transactionInterceptor());
3.查找所有候选的Advisor

因为@Transactional的原理是基于AOP的,所以匹配TransactionInterceptor增强的逻辑,其实就是AOP匹配增强的地方。

Object[] specificInterceptors 
        = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);

大家可以看到,上边就是在创建AOP代理之前,为目标类匹配增强的入口,那么我们就从这里开始分析吧。

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        //先查找所有的候选Advisors
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        //筛选所有的可应用的Advisors 就是解析表达式 
        //判断是否匹配 具体:解析表达式生成匹配器
        //然后和所有的方法进行匹配只要满足就可以加入eligibleAdvisors
        List<Advisor> eligibleAdvisors 
                = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        //在指定下标位置插入一个元素 当前下标元素以后当前下标元素后面的元素往后移动
        //advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
        extendAdvisors(eligibleAdvisors);
        //最后排序
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }

我们知道,在匹配增强的时候,首先就是要找到所有的增强。

@Override
    protected List<Advisor> findCandidateAdvisors() {
        // 根据类型Advisor找
        List<Advisor> advisors = super.findCandidateAdvisors();
        // 解析@Aspect注解声明的增强 查找Advisor
        if (this.aspectJAdvisorsBuilder != null) {
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }
        return advisors;
    }

看下@Aspect注解声明的增强是如何被查找到的

public List<Advisor> buildAspectJAdvisors() {
        //获取所有带有@Aspect注解的类名
        List<String> aspectNames = this.aspectBeanNames;

        if (aspectNames == null) {
            synchronized (this) {
                aspectNames = this.aspectBeanNames;
                if (aspectNames == null) {
                    List<Advisor> advisors = new ArrayList<>();
                    aspectNames = new ArrayList<>();
                    //获取所有的beanName
                    String[] beanNames 
                                = BeanFactoryUtils
                                        .beanNamesForTypeIncludingAncestors(
                                            this.beanFactory, Object.class, true, false);
                    //遍历所有的beanName
                    for (String beanName : beanNames) {
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        Class<?> beanType = this.beanFactory.getType(beanName);
                        if (beanType == null) {
                            continue;
                        }
                        //判断是否有@Aspect注解
                        if (this.advisorFactory.isAspect(beanType)) {
                            aspectNames.add(beanName);
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            if (amd.getAjType().getPerClause().getKind() 
                                                == PerClauseKind.SINGLETON) {
                                //构建解析Aspect的工厂类
                                MetadataAwareAspectInstanceFactory factory =
                                        new BeanFactoryAspectInstanceFactory
                                                        (this.beanFactory, beanName);
                                //解析Aspect下的所有的Advisor 并放入缓存中
                                List<Advisor> classAdvisors
                                    = this.advisorFactory.getAdvisors(factory);
                                if (this.beanFactory.isSingleton(beanName)) {
                                    this.advisorsCache.put(beanName, classAdvisors);
                                }
                                else {
                                    this.aspectFactoryCache.put(beanName, factory);
                                }
                                advisors.addAll(classAdvisors);
                            }
                            else {.
                                if (this.beanFactory.isSingleton(beanName)) {
                                    throw new IllegalArgumentException("");
                                }
                                MetadataAwareAspectInstanceFactory factory
                                    = new PrototypeAspectInstanceFactory
                                                (this.beanFactory, beanName);
                                this.aspectFactoryCache.put(beanName, factory);
                                advisors.addAll(this.advisorFactory.getAdvisors(factory));
                            }
                        }
                    }
                    this.aspectBeanNames = aspectNames;
                    return advisors;
                }
            }
        }

        if (aspectNames.isEmpty()) {
            return Collections.emptyList();
        }
        List<Advisor> advisors = new ArrayList<>();
        //遍历所有的Aspect
        for (String aspectName : aspectNames) {
            //根据AspectName从advisorsCache中获取对应的List<Advisor> 并加入advisors
            List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
            if (cachedAdvisors != null) {
                advisors.addAll(cachedAdvisors);
            }
            else {
                MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
                //如果是AspectJAdvisorFactory接口类型的实现类
                //直接调用getAdvisors 获取对应的List<Advisor> 加入 advisors
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
        }
        return advisors;
    }

先看这一句

this.advisorFactory.getAdvisors(factory);
@Override
    public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
        Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
        validate(aspectClass);

        MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
                new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

        List<Advisor> advisors = new ArrayList<>();
        //获取所有的增强方法:1.非合成非桥接 2.不是@PointCut所在的方法
        for (Method method : getAdvisorMethods(aspectClass)) {
            //构建InstantiationModelAwarePointcutAdvisorImpl实例
            Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
            if (advisor != null) {
                advisors.add(advisor);
            }
        }

        if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory
                                    .getAspectMetadata().isLazilyInstantiated()) {
            Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor
                                                (lazySingletonAspectInstanceFactory);
            advisors.add(0, instantiationAdvisor);
        }

        for (Field field : aspectClass.getDeclaredFields()) {
            Advisor advisor = getDeclareParentsAdvisor(field);
            if (advisor != null) {
                advisors.add(advisor);
            }
        }

        return advisors;
    }
private List<Method> getAdvisorMethods(Class<?> aspectClass) {
        final List<Method> methods = new ArrayList<>();
        /***
         aspectClass:@Aspect注解的类
         */
        ReflectionUtils.doWithMethods(aspectClass, method -> {
            // MethodCallback
            if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
                methods.add(method);
            }
        }, 
        //MethodFilter                              
        ReflectionUtils.USER_DECLARED_METHODS);
        if (methods.size() > 1) {
            methods.sort(METHOD_COMPARATOR);
        }
        return methods;
    }

public static void doWithMethods(Class<?> clazz, MethodCallback mc, @Nullable MethodFilter mf) {
        // 获取所有声明的方法
        Method[] methods = getDeclaredMethods(clazz);
        //遍历方法
        for (Method method : methods) {
            //MethodFilter:非桥接 非合成
            if (mf != null && !mf.matches(method)) {
                continue;
            }
            try {
                //MethodCallback:非@Point声明的方法
                mc.doWith(method);
            }
            catch (IllegalAccessException ex) {
                throw new IllegalStateException();
            }
        }
        //获取父类上的方法
        if (clazz.getSuperclass() != null) {
            doWithMethods(clazz.getSuperclass(), mc, mf);
        }else if (clazz.isInterface()) {
            //获取父接口
            for (Class<?> superIfc : clazz.getInterfaces()) {
                doWithMethods(superIfc, mc, mf);
            }
        }
    }

接下来看这一句代码

getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
            int declarationOrderInAspect, String aspectName) {

        validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
        //判断方法上是否存在增强注解
        AspectJExpressionPointcut expressionPointcut
            = getPointcut(candidateAdviceMethod, 
                        aspectInstanceFactory.getAspectMetadata().getAspectClass());
        if (expressionPointcut == null) {
            return null;
        }
    //构建InstantiationModelAwarePointcutAdvisorImpl
    return new InstantiationModelAwarePointcutAdvisorImpl
                (expressionPointcut, candidateAdviceMethod,
                this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
    }

private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
        //获取增强增强注解 因为Pointcut上面已经被过滤掉了 所以这里只会筛选剩下5种注解修饰的方法
        //@Around,@Before,@After,@AfterReturning,@AfterThrowing
        AspectJAnnotation<?> aspectJAnnotation 
                =AbstractAspectJAdvisorFactory
                    .findAspectJAnnotationOnMethod(candidateAdviceMethod);
        if (aspectJAnnotation == null) {
            return null;
        }
        //构建AspectJExpressionPointcut
        AspectJExpressionPointcut ajexp =
                new AspectJExpressionPointcut
                    (candidateAspectClass, new String[0], new Class<?>[0]);
        ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
        if (this.beanFactory != null) {
            ajexp.setBeanFactory(this.beanFactory);
        }
        //返回AspectJExpressionPointcut
        return ajexp;
    }

总结1下:获取的是非合成非桥接没有被@Pointcut修饰并且有注解增强的方法。

4.查找符合条件的Advisor
/***
1.遍历所有的Advisor其中包含BeanFactoryTransactionAttributeSourceAdvisor

2.获取Advisor的pointcut
BeanFactoryTransactionAttributeSourceAdvisor继承了AbstractBeanFactoryPointcutAdvisor
属于PointcutAdvisor
pointcutAdvisor.getPointcut() 
返回的是 TransactionAttributeSource是1个解析器

3.遍历类的所有方法,调用Pointcut#match判断是否是合适的Advisor
TransactionAttributeSourcePointcut继承自StaticMethodMatcherPointcut 
重写了match方法。
TransactionAttributeSource的match方法主要逻辑:
调用解析器查找方法是否存在@Transactional注解
如果方法上存在@Transactional注解!那么这个Advisor就是可以被使用的
***/
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        //先查找所有的候选Advisors
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        //筛选所有的可应用的Advisors 就是解析表达式 判断是否匹配 
        //具体:解析表达式生成匹配器 
        //然后和所有的方法进行匹配只要满足就可以加入eligibleAdvisors
        List<Advisor> eligibleAdvisors 
                                    = findAdvisorsThatCanApply
                                        (candidateAdvisors, beanClass, beanName);
        //在指定下标位置插入一个元素 当前下标元素以后当前下标元素后面的元素往后移动
        //advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
        extendAdvisors(eligibleAdvisors);
        //最后排序
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }

接下来我们重点看这一行代码

List<Advisor> eligibleAdvisors
                    = findAdvisorsThatCanApply
                                (candidateAdvisors, beanClass, beanName);
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        }
        //符合条件的Advisor
        List<Advisor> eligibleAdvisors = new ArrayList<>();
        //遍历所有的候选Advisor
        for (Advisor candidate : candidateAdvisors) {
            //判断是否是引介增强
            if (candidate instanceof IntroductionAdvisor
                            && canApply(candidate, clazz)) {
                eligibleAdvisors.add(candidate);
            }
        }
        //因为没有引介增强 eligibleAdvisors是空 eligibleAdvisors.isEmpty()=true
        //!eligibleAdvisors.isEmpty()=false
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();
        //遍历所有的Advisor其中包含BeanFactoryTransactionAttributeSourceAdvisor
        for (Advisor candidate : candidateAdvisors) {
            //引介增强上面处理过
            if (candidate instanceof IntroductionAdvisor) {
                continue;
            }
            //进入这里作为普通增强处理 hasIntroductions=false
            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);
        //我们的advisor有2种
        //aop:InstantiationModelAwarePointcutAdvisorImpl
        //事务:BeanFactoryTransactionAttributeSourceAdvisor
        //都是PointcutAdvisor
        }else if (advisor instanceof PointcutAdvisor) {
            PointcutAdvisor pca = (PointcutAdvisor) advisor;
            //对于aop来说
            //pca.getPointcut()返回的是AspectJExpressionPointcut
            //对于事务来说:
            //pca.getPointcut() 返回的是StaticMethodMatcherPointcut
            //TransactionAttributeSource又继承了StaticMethodMatcherPointcut 
            //重写了match方法
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        }
        else {
            return true;
        }
    }

TransactionAttributeSource又继承了StaticMethodMatcherPointcut重写了match方法

public static boolean canApply(Pointcut pc, 
                               Class<?> targetClass,boolean hasIntroductions) {
        //先基于类级别进行过滤 
        //对于事务来说:根据源码版本不同有2种情况
        //1.ClassFilter.TRUE; 永远返回的都是true 
        //2.TransactionAttributeSourceClassFilter;
        //只要目标类既不是java自己的类,也不是Spring里的Ordered接口类型。那么目标类是满足类级别匹配的。
        //对于aop来说:AspectJExpressionPointcut.getClassFilter就是AspectJExpressionPointcut
        //匹配切面表达式和类是否匹配
        if (!pc.getClassFilter().matches(targetClass)) {
            return false;
        }

        //获取方法匹配器
        //pca.getPointcut() 返回的是 TransactionAttributeSource是1个解析器
        //TransactionAttributeSource又继承了StaticMethodMatcherPointcut 
        //重写了match方法
        //目标方法或目标方法所在的类上有没有加@Transactional注解
        MethodMatcher methodMatcher = pc.getMethodMatcher();
        if (methodMatcher == MethodMatcher.TRUE) {
            return true;
        }
        //判断是否是IntroductionAwareMethodMatcher
        IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
        if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
            introductionAwareMethodMatcher = 
                        (IntroductionAwareMethodMatcher) methodMatcher;
        }

        Set<Class<?>> classes = new LinkedHashSet<>();
        //targetClass是我们的代理类 AopLog
        if (!Proxy.isProxyClass(targetClass)) {
            //targetClass = class transaction.AopLog
            classes.add(ClassUtils.getUserClass(targetClass));
        }
        //获取代理类的所有接口
        //  ClassUtils.getAllInterfacesForClassAsSet(targetClass)
        //  0 = {Class@2137} "interface transaction.LogService"
        //  1 = {Class@2138} "interface transaction.PrintService"
        classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

        //每一个advisor的匹配器和class的所有接口方法匹配 
        //只要advisor的匹配器和任何一个方法匹配 就把该方法加入eligible集合
        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;
                }
            }
        }

        return false;
    }
abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {
    //参数1:方法
    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        if (TransactionalProxy.class.isAssignableFrom(targetClass) ||
        PlatformTransactionManager.class.isAssignableFrom(targetClass) ||
        PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
            return false;
        }
        /***
        public AnnotationTransactionAttributeSource() {
                //publicMethodsOnly=true
                this(true);
            }
        ***/
        //注意获取的是AnnotationTransactionAttributeSource
        TransactionAttributeSource tas = getTransactionAttributeSource();
        //调用AnnotationTransactionAttributeSource#getTransactionAttribute
       return (tas == null || tas.getTransactionAttribute
                                        (method, targetClass) != null);
    }

    @Nullable
    protected abstract TransactionAttributeSource getTransactionAttributeSource();
}


    @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) {
            if (cached == NULL_TRANSACTION_ATTRIBUTE) {
                return null;
            }
            else {
                return cached;
            }
        }
        else {
            //调用解析器查找类上或者方法上的@Transactional注解并返回
            TransactionAttribute txAttr = 
                    computeTransactionAttribute(method, targetClass);
            // 如果没找到类上或者方法上的@Transactional注解 那么放到缓存里 下次不用再找了
            if (txAttr == null) {
                this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
            }else {
                // 如果找到类上或者方法上的@Transactional注解 那么放到缓存里 下次不用再找了
                String methodIdentification 
                    = ClassUtils
                        .getQualifiedMethodName(method, targetClass);

                if (txAttr instanceof DefaultTransactionAttribute) {
                    ((DefaultTransactionAttribute) txAttr)
                                    .setDescriptor(methodIdentification);
                }
                //放入缓存
                this.attributeCache.put(cacheKey, txAttr);
            }
            //所以这里返回的是@Transactional注解上的属性
            return txAttr;
        }
    }

先看下AnnotationTransactionAttributeSource#computeTransactionAttribute(method, targetClass);

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
        //是否只允许public方法
        //并且方法的声明是public才能生效 
        if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
            return null;
        }

        Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
        //在方法上找获取@Transactional上的属性
        TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
        if (txAttr != null) {
            return txAttr;
        }
        //在类上找获取@Transactional上的属性
        txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
        if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
            return txAttr;
        }

        if (specificMethod != method) {
            txAttr = findTransactionAttribute(method);
            if (txAttr != null) {
                return txAttr;
            }
            txAttr = findTransactionAttribute(method.getDeclaringClass());
            if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
                return txAttr;
            }
        }

        return null;
    }
protected boolean allowPublicMethodsOnly() {
        return this.publicMethodsOnly;
    }

publicMethodsOnly从哪来的呢?

```

@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
    /***
     true代表是针对public方法 哈哈哈 这下知道为什么非public方法事务会失效了吧?
     public AnnotationTransactionAttributeSource() {
        this(true);
     }
     */

    return new AnnotationTransactionAttributeSource();
}

```

如果上边if语句中的布尔表达式满足的话,就会执行返回null,那么结合上节的文章,我们知道,如果这里返回null的话,那么就代表当前方法不支持事务,最重要的TransactionInterceptor增强就不会生效,由此看来,这个应该是在获取事务属性之前的一个校验条件。

在类ProxyTransactionManagementConfiguration中。

@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        //注入解析器
        //判断是否canApply的时候会用上
        //会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解
        advisor.setTransactionAttributeSource(transactionAttributeSource());
        //设置增强advice 其实就是TransactionInterceptor
        advisor.setAdvice(transactionInterceptor());
        if (this.enableTx != null) {
            advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
        }
        return advisor;
    }
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

    @Nullable
    private TransactionAttributeSource transactionAttributeSource;

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

    public void setTransactionAttributeSource
                (TransactionAttributeSource transactionAttributeSource) {
        //使用事务注解导入的 AnnotationTransactionAttributeSource
        this.transactionAttributeSource = transactionAttributeSource;
    }
}
@SuppressWarnings("serial")
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
        implements Serializable {

    //省略部分代码

    // 无参构造方法
    public AnnotationTransactionAttributeSource() {
        this(true);
    }

    public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
        this.publicMethodsOnly = publicMethodsOnly;
        //省略部分代码
    }

    // 省略部分代码

    // 第一个布尔条件的方法
    @Override
    protected boolean allowPublicMethodsOnly() {
        return this.publicMethodsOnly;
    }

    // 省略部分代码

}

其实allowPublicMethodsOnly()方法只是简单的将变量publicMethodsOnly的值返回了而已。

并且我们可以看到,其实这个publicMethodsOnly的值,在无参构造方法中被默认设置为了true,那么这个publicMethodsOnly是什么含义呢?其实从名字上来看,它是“仅限public方法”的意思,其实就是一个标识罢了,默认为true。

method.getModifiers()其实就是获取方法的修饰符,比如这个方法是public修饰的还是private修饰的,就是这个意思。Modifier.isPublic()方法的意思就非常明显了,说白了就是用来判断当前方法是不是public方法,如果是public方法就返回true,否则返回false。

分析到这里,答案就呼之欲出了,上边的代码说白了就是,在默认情况下,只允许public方法进行事务处理,所以当目标方法不是public方法时,那么红框中的表达式就为true,此时就会返回null。

我们知道,这里一旦返回null,那么当前正在匹配的BeanFactoryTransactionAttributeSourceAdvisor增强就不会加入到eligibleAdvisors中,从而导致TransactionInterceptor增强不会生效,那么此时就表示,该目标类不需要被代理,也就是不会添加事务管理的功能。

这个其实就是在非public方法上,添加@Transactional事务失效的底层原因!

获取目标类或者目标方法上的@Transactional事务属性

主要调用了一个findTransactionAttribute()方法,并且将目标方法作为入参传递了进去,接着findTransactionAttribute()方法就会给我们返回事务属性TransactionAttribute。

@Nullable
    protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
        for (TransactionAnnotationParser annotationParser : this.annotationParsers) {
            TransactionAttribute attr = annotationParser.parseTransactionAnnotation(element);
            if (attr != null) {
                return attr;
            }
        }
        return null;
    }

其实从findTransactionAttribute()方法的名字上也可以看出,这个方法就是用来寻找事务属性的,ok,那现在我们就跟进去看看这个findTransactionAttribute()方法吧。

在findTransactionAttribute()方法中,又调用了determineTransactionAttribute()方法,所以核心逻辑还是在determineTransactionAttribute()方法中的。

而在determineTransactionAttribute()方法的逻辑其实很简单,就是遍历annotationParsers集合中的事务注解解析器,然后通过事务注解解析器的parseTransactionAnnotation()方法完成事务属性的解析。

通过debug我们可以看到,其实在annotationParsers集合中呢,就只有SpringTransactionAnnotationParser这一个注解解析器,那这就简单了,说白了就是,这里其实就是通过SpringTransactionAnnotationParser注解解析器来完成事务属性解析的。

ok,那现在还犹豫啥呢,我们直接进去SpringTransactionAnnotationParser瞅一眼呗,此时会看到下边的代码。

//目标类上找
    @Override
    @Nullable
    protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
        return determineTransactionAttribute(clazz);
    }
    //目标方法上找
    @Override
    @Nullable
    protected TransactionAttribute findTransactionAttribute(Method method) {
        return determineTransactionAttribute(method);
    }
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
        AnnotationAttributes attributes = AnnotatedElementUtils
                                .findMergedAnnotationAttributes(
                                    element, Transactional.class, false, false);
        if (attributes != null) {
            return parseTransactionAnnotation(attributes);
        }
        else {
            return null;
        }
    }

我们可以看到,这里其实主要调用了工具类AnnotatedElementUtils中的findMergedAnnotationAttributes()方法来寻找事务属性的。

并且我们可以看到,在findMergedAnnotationAttributes()方法的入参中,有目标方法element和注解Transactional.class,说白了这里就是,要在目标方法上寻找@Transactional注解中配置的属性!

而这个findMergedAnnotationAttributes()方法呢,是工具类AnnotatedElementUtils中的静态方法,专门是用于在指定element上寻找特定注解的,比如在目标方法上寻找@Transactional事务注解。

其实这个AnnotatedElementUtils工具类呢,是在spring-core包下的,所以不是我们这里分析的重点,因此这个方法,我们就不往下深入分析了,有兴趣的同学可以往下继续跟踪下,我们就不花费时间在这里了。

那我们继续往下看,在获取到事务属性之后,就会调用parseTransactionAnnotation()方法做进一步处理,代码如下

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

大家可以看到,其实这个parseTransactionAnnotation()方法要做的事情呢,就是将刚刚获取到的事务属性进一步封装到RuleBasedTransactionAttribute中去,这样方便后续的处理,最后就会将封装好的RuleBasedTransactionAttribute作为结果返回。

而当computeTransactionAttribute()方法将事务属性返回之后,发现事务属性不为null,那这个时候就会将事务属性放入缓存attributeCache中,接着getTransactionAttribute()方法就会将事务属性返回。

else{
                // 如果找到方法上的@Transactional注解 那么放到缓存里 下次不用再找了
                String methodIdentification 
                    = ClassUtils
                        .getQualifiedMethodName(method, targetClass);

                if (txAttr instanceof DefaultTransactionAttribute) {
                    ((DefaultTransactionAttribute) txAttr)
                                    .setDescriptor(methodIdentification);
                }
                //放入缓存
                this.attributeCache.put(cacheKey, txAttr);
            }
            //所以这里返回的是@Transactional注解上的属性
            return txAttr;

可以看到,这里就会根据getTransactionAttribute()方法返回的事务属性进行判断,如果获取的事务属性不为null的话,那么就说明匹配成功,也就是说,此时目标类是需要被代理的!

上边呢,是获取事务属性不为null的情况,下边我们来看下另外一种情况,那就是获取到的事务属性为null的情况。

如果获取到的事务属性为null的话,则会返回false,那么此时BeanFactoryTransactionAttributeSourceAdvisor就不会加入到eligibleAdvisors中,从而导致TransactionInterceptor增强不会生效,那么此时就表示该目标方法不会被代理,也就是不会添加事务管理的功能。

所以对于@Transactional注解来说,在方法级别的匹配,说白了就是,看下能不能获取到@Transactional注解中配置的属性。

如果可以获取到事务属性的话,那么就表示BeanFactoryTransactionAttributeSourceAdvisor增强匹配成功,此时就会按照配置的事务属性来管理事务了。

而如果获取不到事务属性的话,那么BeanFactoryTransactionAttributeSourceAdvisor增强就不会生效,此时就说明当前目标方法所在的类不需要被代理,所以也就没有事务管理的功能了。

获取目标类上的@Transactional的事务属性

刚才呢,我们分析的是,在方法上顺利找到@Transactional注解的情况,那么另外一种情况,那就是可能在目标方法上是找不到@Transactional注解的,那么这种情况下,Spring又是怎么处理的呢?

我们此时假设,在目标方法上没有找到@Transactional注解。

也就是说,当在方法上找不到@Transactional注解时,那么txAttr就为null,那此时txAttr != null的结果就为false,那此时代码就会继续往下执行,也就是会执行下面的代码。

txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
        if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
            return txAttr;
        }

并且我们可以看到,这里调用的还是findTransactionAttribute()方法,和刚才在目标方法寻找事务属性是同一个方法。

通过上图,我们可以看到,方法名是一样的,而入参不一样,之前在目标方法上寻找事务属性时,入参传递的是目标方法本身,而这里在目标类上寻找事务属性时,入参传的是目标类本身,所以我们猜测这个findTransactionAttribute()方法可能是有两个重载方法,说白了就是方法名相同,但方法参数类型不同。

那到底是不是如我们猜测的那样呢?

我们进去看下就知道了,此时我们跟着进去findTransactionAttribute(specificMethod.getDeclaringClass())方法,会看到下边.

//目标类上找
    @Override
    @Nullable
    protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {
        return determineTransactionAttribute(clazz);
    }
    //目标方法上找
    @Override
    @Nullable
    protected TransactionAttribute findTransactionAttribute(Method method) {
        return determineTransactionAttribute(method);
    }
public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
        AnnotationAttributes attributes = AnnotatedElementUtils
                                .findMergedAnnotationAttributes(
                                    element, Transactional.class, false, false);
        if (attributes != null) {
            return parseTransactionAnnotation(attributes);
        }
        else {
            return null;
        }
    }

上边的代码中,一个是在目标类级别上找事务属性的方法,一个是在目标方法级别找事务属性的方法,可以看到,它们都同时调用了determineTransactionAttribute()方法。

这就奇怪了,为啥这里在目标类上,寻找事务注解还是调用这个方法呢?难道是这个determineTransactionAttribute()方法同时支持在类上和方法上查找注解?

我们注意到,其实这个方法的入参是AnnotatedElement类型,从名字上来看,这个AnnotatedElement是“注释元素”的意思,那么这个AnnotatedElement到底代表哪些元素呢?

这个简单,其实我们点进去,来看下AnnotatedElement的定义就知道了。

image.png

我们可以看到,其实我们平常经常使用的Class和Method,甚至Field和Constructor,它们都是AnnotatedElement接口的实现类,也就是说,它们都属于“注释元素”。AnnotatedElement接口的一个实例,就表示当前JVM中的一个“被注解元素”,而这个被注解的元素可以是Class、Method、Field、Constructor等等。所以话说回来,由于这个determineTransactionAttribute()方法处理的AnnotatedElement接口类型,也就是说人家处理的是“被注解的元素。

既然处理的是被注解的元素,那当然就包含了Class、Method、Field、Constructor等元素,所以人家当然既可以来处理类上的事务属性和方法上的事务属性啦。

所以一句话,在类上寻找事务注解的逻辑,和在方法上寻找事务注解的逻辑是一模一样的,它们都是通过调用determineTransactionAttribute()方法来完成的!而最后,其实就是通过SpringTransactionAnnotationParser事务注解解析器来完成解析的。

假如我们此时在类上找到了事务属性,那么这个时候就会将事务属性给返回。

那大家思考下,现在这个情况,大概是一个怎样的业务场景呢?

其实啊,这个业务场景就是,@Transactional注解没有加在方法上,而是加在了类上!

虽然我们在工作中,一般不会加在类上,但是@Transactional注解本身,人家是既支持加在方法上,也支持加在类上的,所以在解析@Transactional注解的时候,Spring会优先从方法上获取事务属性,如果方法上找不到事务属性的话,那么接着就会看下方法所在的类上,是否加了@Transactional注解,就是这个意思。

在类级别和方法级别都满足后,就会将匹配成功的增强返回,而这里返回的增强其实就是BeanFactoryTransactionAttributeSourceAdvisor,我们知道,在BeanFactoryTransactionAttributeSourceAdvisor中有一个非常关键的属性,那就是adviceBeanName,它的值就是TransactionInterceptor类的全限定类名,而这个TransactionInterceptor的重要性,我们这里就不再赘述了。

一旦这个BeanFactoryTransactionAttributeSourceAdvisor增强被加入eligibleAdvisors中,就意味着事务功能添加成功了!那有的同学会问:“什么?我到现在还是没看到TransactionInterceptor增强啊”

image.png

其实呢,大家注意看上图中的红框,我们会发现在BeanFactoryTransactionAttributeSourceAdvisor中,有一个属性叫做adviceBeanName,而这个adviceBeanName的值就是TransactionInterceptor的全限定类名。

所以,我们心心念的TransactionInterceptor,其实就是BeanFactoryTransactionAttributeSourceAdvisor中的一个属性罢了,只不过这里是一个全限定类名,但是到后边一定会通过这个全限定类名来构建TransactionInterceptor实例的。

因为源码版本不同 所以略有差异,我这个版本是直接设置transactionInterceptor进去。

//看这里
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        //注入解析器
        //判断是否canApply的时候会用上
        //会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解
        advisor.setTransactionAttributeSource(transactionAttributeSource());
        //设置增强advice
        advisor.setAdvice(transactionInterceptor());
        if (this.enableTx != null) {
            advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
        }
        return advisor;
    }
4.生成代理对象
5.执行方法创建拦截器链

事务AOP代理是怎么来匹配BeanFactoryTransactionAttributeSourceAdvisor增强的?

那我们这里,就以jdk代理为例,当调用代理对象中的方法时,就会调用到JdkDynamicAopProxy的invoke()方法,而invoke()方法的核心代码如下。

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 省略部分代码
        try {
            // 省略部分代码

            // 获取当前要调用方法的拦截器链,advised就是一个ProxyFactory
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

            // 处理拦截器链
            if (chain.isEmpty()) {
                // 如果拦截器链为空,则使用反射调用目标方法
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection
                                            (target, method, argsToUse);
            }
            else {
                //如果拦截器链不为空,则将拦截器统一封装为MethodInvocation
                //同时传入目标对象target和目标方法method,后续反射调用目标方法会使用到
                MethodInvocation invocation =
                        new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // 处理拦截器链,也就是依次执行每一个拦截器
                retVal = invocation.proceed();
            }

            // 省略部分代码

            // 将返回值作为结果返回
            return retVal;
        }
        finally {
            // 省略部分代码
        }
    }

其实JdkDynamicAopProxy的invoke()方法,我们在AOP章节详细分析过,这里呢,主要是站在事务代理的角度,来分析下事务代理的执行过程。

通过上边代码,可以看到,其实invoke()方法核心逻辑就两块,一个是获取拦截器链,一个是执行拦截器链,而执行拦截器链,在一开始讲@Transactional注解的时候就分析过了,下边我们主要来看下获取拦截器链的逻辑。

那我们现在就来看下getInterceptorsAndDynamicInterceptionAdvice()方法

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
        MethodCacheKey cacheKey = new MethodCacheKey(method);
        List<Object> cached = this.methodCache.get(cacheKey);
        if (cached == null) {
            cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
                    this, method, targetClass);
            this.methodCache.put(cacheKey, cached);
        }
        return cached;
    }
@Override
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
            Advised config, Method method, @Nullable Class<?> targetClass) {

        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        //获取proxyFactory的advisors
        Advisor[] advisors = config.getAdvisors();
        List<Object> interceptorList = new ArrayList<>(advisors.length);
        Class<?> actualClass 
                = (targetClass != null ? targetClass : method.getDeclaringClass());
        Boolean hasIntroductions = null;
        //遍历advisors
        for (Advisor advisor : advisors) {
            //判断类级别匹配
            if (advisor instanceof PointcutAdvisor) {
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
                //不管是事务还是aop预过滤一般都是true
                //InfrastructureAdvisorAutoProxyCreator
                //AnnotationAwareAspectJAutoProxyCreator
                //都继承自AbstractAdvisorAutoProxyCreator
                //AbstractAdvisorAutoProxyCreator#advisorsPreFiltered

                //第二个条件:
                //对于aop来说:使用切面表达式和类匹配
                //对于事务来说:使用ClassFilter.TRUE 永远返回true
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut()
                                                .getClassFilter().matches(actualClass)) {
                    //方法匹配器
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    boolean match;
                    //方法签名匹配
                    if (mm instanceof IntroductionAwareMethodMatcher) {
                        if (hasIntroductions == null) {
                            hasIntroductions = hasMatchingIntroductions
                                                        (advisors, actualClass);
                        }
                        match = ((IntroductionAwareMethodMatcher) mm)
                                    .matches(method, actualClass, hasIntroductions);
                    }
                    else {
                        match = mm.matches(method, actualClass);
                    }
                    //匹配通过
                    if (match) {
                        //获取拦截器
                        MethodInterceptor[] interceptors
                                    = registry.getInterceptors(advisor);
                        if (mm.isRuntime()) {
                            for (MethodInterceptor interceptor : interceptors) {
                                interceptorList
                                    .add(new InterceptorAndDynamicMethodMatcher
                                        (interceptor, mm));
                            }
                        }
                        else {
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                }
            }
            else if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
                if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                    Interceptor[] interceptors = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            }
            else {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }
        return interceptorList;
    }
@Override
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List<MethodInterceptor> interceptors = new ArrayList<>(3);
        Advice advice = advisor.getAdvice();
        //将transactionInterceptor放入拦截器链
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor) advice);
        }
        for (AdvisorAdapter adapter : this.adapters) {
            if (adapter.supportsAdvice(advice)) {
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }
        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        }
        return interceptors.toArray(new MethodInterceptor[0]);
    }

getAdvice方法对于Aop来说是使用增强注解和方法匹配返回MethodInterceptor。

getAdvice方法对于事务来说是使用adviceBeanName 来获取TransactionInterceptor。

public Advice getAdvice() {
        Advice advice = this.advice;
        //这个advice在构建BeanFactoryTransactionAttributeSourceAdvisor时已经创建了
        if (advice != null) {
            return advice;
        }

        Assert.state(this.adviceBeanName != null, "'adviceBeanName' must be specified");
        Assert.state(this.beanFactory != null, "BeanFactory must be set to comresolve 'adviceBeanName'");

        if (this.beanFactory.isSingleton(this.adviceBeanName)) {
            // Rely on singleton semantics provided by the factory.
            advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
            this.advice = advice;
            return advice;
        }
        else {
            synchronized (this.adviceMonitor) {
                advice = this.advice;
                if (advice == null) {
                    advice = this.beanFactory.getBean(this.adviceBeanName, Advice.class);
                    this.advice = advice;
                }
                return advice;
            }
        }
    }

//看这里
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
        BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
        //注入解析器
        //判断是否canApply的时候会用上
        //会调用getTransactionAttributeSource 获取解析器 解析@Transaction注解
        advisor.setTransactionAttributeSource(transactionAttributeSource());
        //设置增强advice
        advisor.setAdvice(transactionInterceptor());
        if (this.enableTx != null) {
            advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
        }
        return advisor;
    }

首先第一步,就是从代理配置ProxyFactory中,获取到当时设置的增强,也就是BeanFactoryTransactionAttributeSourceAdvisor。

然后第二步,就是在类级别进行匹配,这个前边我们刚讲过的哈,其实对于@Transactional注解类级别的匹配来说,只要目标类既不是java自己的类,也不是Spring里的Ordered接口类型,那么此时就表示目标类是满足类级别匹配的。(源码版本不同,我的源码是一直返回true)

如果在类级别匹配成功的话,那么就进行第三步的处理,其实第三步的话,就是在方法级别进行匹配,匹配逻辑呢,前边我们刚讲过,其实就是看下目标方法或目标方法所在的类上有没有加@Transactional注解,如果加的话,那么就说明在方法级别匹配成功。

最后第四步的话,就是为匹配成功的增强构建拦截器了。

对于事务AOP代理来说,其实拦截器链chain中只有一个TransactionInterceptor拦截器,而TransactionInterceptor拦截器执行的整个过程,我们在事务源码分析的开头,就已经分析过了,所以这里就不再赘述了,说白了TransactionInterceptor拦截器就是基于jdbc的API来控制数据库事务的

下面看这一段代码:

// 处理拦截器链
            if (chain.isEmpty()) {
                // 如果拦截器链为空,则使用反射调用目标方法
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection
                                            (target, method, argsToUse);
            }
            else {
                // 如果拦截器链不为空,则将拦截器统一封装为MethodInvocation
                // 同时传入目标对象target和目标方法method,后续反射调用目标方法会使用到
                MethodInvocation invocation =
                        new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // 处理拦截器链,也就是依次执行每一个拦截器
                retVal = invocation.proceed();
            }
6.TransactionInterceptor
@Override
    @Nullable
    public Object invoke(MethodInvocation invocation) throws Throwable {
        //将ReflectiveMethodInvocation的proceed方法作为参数传递
        return invokeWithinTransaction
        (invocation.getMethod(), targetClass, invocation::proceed;
    }
//invocation 拦截器核心逻辑

    @Nullable
    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 || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {

            // 开启事务
            TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);

            Object retVal;
            try {

                // 调用目标方法
                retVal = invocation.proceedWithInvocation();
            }
            catch (Throwable ex) {
                // 回滚事务
                completeTransactionAfterThrowing(txInfo, ex);
                throw ex;
            }
            finally {
                cleanupTransactionInfo(txInfo);
            }

            if (vavrPresent && VavrDelegate.isVavrTry(retVal)) {
                TransactionStatus status = txInfo.getTransactionStatus();
                if (status != null && txAttr != null) {
                    retVal = VavrDelegate.evaluateTryFailure
                                            (retVal, txAttr, status);
                }
            }

            // 提交事务
            commitTransactionAfterReturning(txInfo);
            return retVal;
        }
        else {
            //省略部分代码
        }
    }

上边就是invokeWithinTransaction()方法的核心代码了,其中一些不太重要的代码已经省略了

我们可以看到,上边的代码中,首先是调用了一个createTransactionIfNecessary()方法,从这个方法的名字上来看是“创建事务”的意思,其实说白了就是开启事务的意思。

接着调用了retVal = invocation.proceedWithInvocation()这行代码来执行目标方法,而这行代码呢,做了try catch处理,在这个catch语句块中调用了一个completeTransactionAfterThrowing()方法,这个方法从名字来看是“发生异常后完成事务”,其实说白了就是发生异常时回滚事务的意思,并且回滚完事务之后,通过throw ex将异常直接抛了出去。

如果执行目标方法没有发生异常,那么就会调用commitTransactionAfterReturning()方法,从名字上来看这个方法是“返回后提交事务”的意思,其实说白了就是目标方法正常执行结束后,如果没有发生异常,那么就直接提交事务的意思。

大家有没有发现,上边这块代码的逻辑,和上节我们基于AOP模拟事务的代码非常相似?简直就是一个模子里刻出来的。

其实啊,@Transactional注解的本质就是基于AOP来实现的,而实现事务的核心逻辑,其实就是在执行目标方法之前,先开启事务,然后再来执行目标方法,因为目标方法是加了try catch处理的,所以当执行目标方法发生异常时,由catch语句块来做特殊处理,说白了就是回滚事务,如果未发生异常,那么就直接提交事务,就这么简单。

7.查找对应的事务管理器
@Nullable
protected PlatformTransactionManager determineTransactionManager(@Nullable TransactionAttribute txAttr) {
        // Do not attempt to lookup tx manager if no tx attributes are set
        if (txAttr == null || this.beanFactory == null) {
            return getTransactionManager();
        }
        //获取@Transactional注解的value属性
        //如果没有指定 默认是""
        //myPlatformTransactionManager
        String qualifier = txAttr.getQualifier();
        //如果不为空字符串进入这里
        //如果指定了值 那么使用指定的名称和类型PlatformTransactionManager去找
        //找到了直接返回
        if (StringUtils.hasText(qualifier)) {
            return determineQualifiedTransactionManager
                                (this.beanFactory, qualifier);
        }
        else if (StringUtils.hasText(this.transactionManagerBeanName)) {
            return determineQualifiedTransactionManager(this.beanFactory, this.transactionManagerBeanName);
        }else {
            //调用TransactionInterceptor的getTransactionManager方法
            //获取PlatformTransactionManager
            PlatformTransactionManager defaultTransactionManager 
                                                = getTransactionManager();
            if (defaultTransactionManager == null) {
                //缓存中获取
                defaultTransactionManager 
                        = this.transactionManagerCache.get
                                (DEFAULT_TRANSACTION_MANAGER_KEY);
                
                if (defaultTransactionManager == null) {
                    //根据类型获取
                    //但是如果根据类型查找如果有多个会有问题!
                    defaultTransactionManager
                        = this.beanFactory.getBean
                                (PlatformTransactionManager.class);
                    //放入缓存
                    this.transactionManagerCache.putIfAbsent(
                                                DEFAULT_TRANSACTION_MANAGER_KEY, 
                                                defaultTransactionManager);
                }
            }
            return defaultTransactionManager;
        }
    }

总结

1.获取所有的advisor

2.获取可用的advisor

3.从advisor中获取advice然后适配为MethodInterceptor

4.调用代理类的方法时会根据调用的方法匹配所有的MethodInterceptor组成chain

5.递归调用chain

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值