Spring源码学习3——事务

Spring事务源码分析

1.确定事务管理方式【注册BD】

  • 启动注解导入一个TransactionManagementConfigurationSelector:
  • 根据mode属性使用不同风格的事务管理方式。注册一个AutoProxyResitry
  • 根据mode属性和proxyTargetClass属性用不同方法将之注册到容器。

观察开始事务注解导入了一个TransactionManagementConfigurationSelector:
在这里插入图片描述

观察TransactionManagementConfigurationSelector:
在这里插入图片描述
点进去AutoProxyRegistrar:
在这里插入图片描述

2.自定义属性读取

  • 之前aop流程,bean初始化后置会创建代理对象,此过程需要找出方法增强器,创建代理【wrapIfNecessary】
  • 寻找候选增强器,再从候选增强器种寻找到匹配项。从候选增强器种寻找到匹配项时
  • 如果是引介增强器【IntroductionAdvisor】且满足过滤器,直接匹配
  • 如果是切点增强器【PointcutAdvisor】,查看其切点是否匹配【canApplly】,
  • 而Bean工厂事务属性源增强器【BeanFactoryTransationAttributeSourceAdviosr】在此分支。里面会提取事务的自定义属性

找增强器时:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		//寻找候选增强器
        List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
        //从候选增强器种寻找到匹配项
        List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        this.extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = this.sortAdvisors(eligibleAdvisors);
        }

        return eligibleAdvisors;
    }

关注第二个寻找匹配项的方法,底层调用AopUtils.findAdvisorsThatCanApply,观察它:
如果是IntroductionAdvisor类型,并且可以应用到目标类【canApply】,添加到一个容器

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        } else {
            List<Advisor> eligibleAdvisors = new ArrayList();
            Iterator var3 = candidateAdvisors.iterator();

            while(var3.hasNext()) {
                Advisor candidate = (Advisor)var3.next();
                if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                    eligibleAdvisors.add(candidate);
                }
            }

            boolean hasIntroductions = !eligibleAdvisors.isEmpty();
            Iterator var7 = candidateAdvisors.iterator();

            while(var7.hasNext()) {
                Advisor candidate = (Advisor)var7.next();
                if (!(candidate instanceof IntroductionAdvisor) && canApply(candidate, clazz, hasIntroductions)) {
                    eligibleAdvisors.add(candidate);
                }
            }

            return eligibleAdvisors;
        }
    }

观察canApply方法:

	public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
        if (advisor instanceof IntroductionAdvisor) {
        	//如果是引介增强器【IntroductionAdvisor】且满足过滤器
            return ((IntroductionAdvisor)advisor).getClassFilter().matches(targetClass);
        } else if (advisor instanceof PointcutAdvisor) {
        	//或者是切点增强器【PointcutAdvisor】类型
            PointcutAdvisor pca = (PointcutAdvisor)advisor;
            return canApply(pca.getPointcut(), targetClass, hasIntroductions);
        } else {
            return true;
        }
    }

而Bean工厂事务属性源增强器【BeanFactoryTransationAttributeSourceAdviosr】是一个切点增强器【PointcutAdvisor】
所以走第二分支,调用getPointcut继续调用canApply方法

3.事务增强器【TransactionInterceptor】

  • 获取事务属性和管理器,判断是声明式还是编程式事务,执行不同逻辑
  • 如果是声明式事务,尝试获取创建一个【ReactiveTransactionSupport】
  • 针对目标方法返回类型【Mono、Flux】来创建、提交、回滚事务
@Nullable
    protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, InvocationCallback invocation) throws Throwable {
        TransactionAttributeSource tas = this.getTransactionAttributeSource();
        //获取事务属性
        TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null;
		//获取事务管理器
        TransactionManager tm = this.determineTransactionManager(txAttr);
        if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
            ReactiveTransactionSupport txSupport = (ReactiveTransactionSupport)this.transactionSupportCache.computeIfAbsent(method, (key) -> {
                if (KotlinDetector.isKotlinType(method.getDeclaringClass()) && TransactionAspectSupport.KotlinDelegate.isSuspend(method)) {
                    throw new TransactionUsageException("Unsupported annotated transaction on suspending function detected: " + method + ". Use TransactionalOperator.transactional extensions instead.");
                } else {//如果不是Kotlin 类型或者不是挂起函数
                    ReactiveAdapter adapter = this.reactiveAdapterRegistry.getAdapter(method.getReturnType());
                    //找不到对应的ReactiveAdapter 抛出异常
                    if (adapter == null) {
                        throw new IllegalStateException("Cannot apply reactive transaction to non-reactive return type: " + method.getReturnType());
                    } else {//找得到创建一个辅助类【ReactiveTransactionSupport】
                        return new ReactiveTransactionSupport(adapter);
                    }
                }
            });
            return txSupport.invokeWithinTransaction(method, targetClass, invocation, txAttr, (ReactiveTransactionManager)tm);
        } else {
            。。。。。。//编程式事务处理
    }

观察事务支持辅助类:

public Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, InvocationCallback invocation, @Nullable TransactionAttribute txAttr, ReactiveTransactionManager rtm) {
            String joinpointIdentification = TransactionAspectSupport.this.methodIdentification(method, targetClass, txAttr);
            return Mono.class.isAssignableFrom(method.getReturnType()) ? TransactionContextManager.currentContext().flatMap((context) -> {
                return this.createTransactionIfNecessary(rtm, txAttr, joinpointIdentification).flatMap((it) -> {
                    try {
                        return Mono.usingWhen(Mono.just(it), (txInfo) -> {
                            try {
                                return (Mono)invocation.proceedWithInvocation();
                            } catch (Throwable var3) {
                                return Mono.error(var3);
                            }
                        }, this::commitTransactionAfterReturning, (txInfo, err) -> {
                            return Mono.empty();
                        }, this::commitTransactionAfterReturning).onErrorResume((ex) -> {
                            return this.completeTransactionAfterThrowing(it, ex).then(Mono.error(ex));
                        });
                    } catch (Throwable var4) {
                        return this.completeTransactionAfterThrowing(it, var4).then(Mono.error(var4));
                    }
                });
            }).subscriberContext(TransactionContextManager.getOrCreateContext()).subscriberContext(TransactionContextManager.getOrCreateContextHolder()) : this.adapter.fromPublisher(TransactionContextManager.currentContext().flatMapMany((context) -> {
                return this.createTransactionIfNecessary(rtm, txAttr, joinpointIdentification).flatMapMany((it) -> {
                    try {
                        return Flux.usingWhen(Mono.just(it), (txInfo) -> {
                            try {
                                return this.adapter.toPublisher(invocation.proceedWithInvocation());
                            } catch (Throwable var4) {
                                return Mono.error(var4);
                            }
                        }, this::commitTransactionAfterReturning, (txInfo, ex) -> {
                            return Mono.empty();
                        }, this::commitTransactionAfterReturning).onErrorResume((ex) -> {
                            return this.completeTransactionAfterThrowing(it, ex).then(Mono.error(ex));
                        });
                    } catch (Throwable var4) {
                        return this.completeTransactionAfterThrowing(it, var4).then(Mono.error(var4));
                    }
                });
            }).subscriberContext(TransactionContextManager.getOrCreateContext()).subscriberContext(TransactionContextManager.getOrCreateContextHolder()));
        }

4.总结

1.启动类注解引入了一个TransactionManagementConfigurationSelector

  • 根据mode属性选择对应的事务管理方式
  • 配置了一个AutoProxyRegistrar,再容器启动第二步将BD注册到容器
    2.再bean初始化后置处理器的后置方法阶段,生成代理对象
  • 创建代理时,会获取到事务增强器,
  • 提供在目标方法开始前开启事务,结束后关闭事务,失败事务回滚等功能
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值