美文网首页
Spring事务实现原理

Spring事务实现原理

作者: 神易风 | 来源:发表于2022-07-26 22:37 被阅读0次

    代理对象在哪里创建

    先从bean被创建后如何产生代理对象开始,在AbstractAutowireCapableBeanFactory.doCreateBean 初始化bean创建后,并且将依赖注入到bean中,在调用initializeBean 方法对刚刚完成依赖注入bean进行一次"初始化"

        protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
            if (System.getSecurityManager() != null) {
                AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                    invokeAwareMethods(beanName, bean);
                    return null;
                }, getAccessControlContext());
            }
            else {
                invokeAwareMethods(beanName, bean);
            }
    
            Object wrappedBean = bean;
            if (mbd == null || !mbd.isSynthetic()) {
                wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
            }
    
            try {
                invokeInitMethods(beanName, wrappedBean, mbd);
            }
            catch (Throwable ex) {
            }
            if (mbd == null || !mbd.isSynthetic()) {
                //就是在这里对符合条件bean 转换成 代理对象  对象 -> AnnotationAwareAspectJAutoProxyCreator
                wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
            }
    
            return wrappedBean;
        }
    

    AbstractAutoProxyCreator.postProcessAfterInitialization

        public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
            if (bean != null) {
                //判断Class FactoryBean 实现类,修改bean名字 在beanName前面加上&
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
                if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                    return wrapIfNecessary(bean, beanName, cacheKey); //这里将会返回代理后的对象
                }
            }
            return bean;
        }
    
        protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            //targetSourcedBeans 没有生成代理bean 缓存
            if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
                return bean;
            }
            //advisedBeans 也是缓存,返回false 则不会生成代理对象
            if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                return bean;
            }
            //ORIGINAL 后置表明bean 实例不会变,则不会生成代理对象
            if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
    
            // Create proxy if we have advice.
            //这里会返回 BeanFactoryTransactionAttributeSourceAdvisor,如果不创建代理对象,这里就会返回空数组
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE); //缓存已经解析过bean,后面就不用再解析一次class
                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;
        }
    
        protected Object[] getAdvicesAndAdvisorsForBean(
                Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
            //使用Advisor 去处理class 是否需要生成代理对象,如果需要则返回 advisors 不为空
            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 使用一个Advisor 生成Advisor 通过代理工厂生成一堆代理对象
            //这里会返回 BeanFactoryTransactionAttributeSourceAdvisor
            List<Advisor> candidateAdvisors = findCandidateAdvisors();
    
            List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
            extendAdvisors(eligibleAdvisors);
            if (!eligibleAdvisors.isEmpty()) {
                eligibleAdvisors = sortAdvisors(eligibleAdvisors);
            }
            return eligibleAdvisors;
        }
    

    上面判断主要做一些检查,当所有状态合法后才会进入getAdvicesAndAdvisorsForBean返回通过指定bean生成的通知,在通过Advisor数组生成代理对象。这个方法主要逻辑就是通过

    BeanFactoryTransactionAttributeSourceAdvisor 工厂内置Advisor解析Class并且生成pointcut 切点。主要实现在AopUtils

        /**
        * candidateAdvisors 内置Advisor 也就是BeanFactoryTransactionAttributeSourceAdvisor
        *  给定Class 找寻可用Advisor
        */
        public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
            if (candidateAdvisors.isEmpty()) {
                return candidateAdvisors;
            }
            List<Advisor> eligibleAdvisors = new ArrayList<>();
            // IntroductionAdvisor只能应用于类级别 事务一般定位到Method上,不会使用这种类型Advisor
            for (Advisor candidate : candidateAdvisors) {
                if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                    eligibleAdvisors.add(candidate);
                }
            }
            boolean hasIntroductions = !eligibleAdvisors.isEmpty();
            for (Advisor candidate : candidateAdvisors) {
                if (candidate instanceof IntroductionAdvisor) {
                    // already processed
                    continue;
                }
                            // 这里会使用candidate 去解析Class 如果需要生成代理方法或者代理对象 将会返回true
                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
                PointcutAdvisor pca = (PointcutAdvisor) advisor;
                return canApply(pca.getPointcut(), targetClass, hasIntroductions);
            }
            else {
                // It doesn't have a pointcut so we assume it applies.
                return true;
            }
        }
            //pointcut 为 TransactionAttributeSourcePointcut 内部类
        public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
            Assert.notNull(pc, "Pointcut must not be null");
            if (!pc.getClassFilter().matches(targetClass)) {
                return false;
            }
                    //方法匹配器,用于解析Method 是否需要生成代理方法
            MethodMatcher methodMatcher = pc.getMethodMatcher();
            if (methodMatcher == MethodMatcher.TRUE) { //没有任何逻辑,没有方法都会生成代理方法
                // No need to iterate the methods if we're matching any method anyway...
                return true;
            }
    
            IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
            if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
                introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
            }
    
            Set<Class<?>> classes = new LinkedHashSet<>();
            if (!Proxy.isProxyClass(targetClass)) { //向上获取父类class,排除掉代理class
                classes.add(ClassUtils.getUserClass(targetClass));
            }
            classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(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;
                    }
                }
            }
    
            return false;
        }
    

    本质依然是使用BeanFactoryTransactionAttributeSourceAdvisor 内部对象来匹配Class 或Method,并且生成Advisor。
    主要流程使用BeanFactoryTransactionAttributeSourceAdvisor.Pointcut(TransactionAttributeSourcePointcut 抽象类) -> TransactionAttributeSourcePointcut.matches ->AbstractFallbackTransactionAttributeSource.getTransactionAttribute
    -> AnnotationTransactionAttributeSource.findTransactionAttribute ->AnnotationTransactionAttributeSource.determineTransactionAttribute -> TransactionAnnotationParser.TransactionAttribute

    其中在AnnotationTransactionAttributeSource.determineTransactionAttribute 方法会使用Spring 支持TransactionAnnotationParser 数组去解析method并且返回TransactionAttribute
    TransactionAnnotationParser是Spring 事务注解解析器接口在Class、Method 上解析注解并且将声明注解解析成TransactionAttribute 支持3种实现

    • SpringTransactionAnnotationParser Spring自身数据库事务 解析@Transactional
    • Ejb3TransactionAnnotationParser EJB事务 解析 javax.ejb.TransactionAttribute
    • JtaTransactionAnnotationParser JTA1.2 事务 解析javax.transaction.Transactional

    我们一起看下如何生成代理对象的createProxy

        protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
                @Nullable Object[] specificInterceptors, TargetSource targetSource) {
    
            if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
                AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
            }
    
            ProxyFactory proxyFactory = new ProxyFactory();
            proxyFactory.copyFrom(this);
    
            if (!proxyFactory.isProxyTargetClass()) { // 如果还没有设置代理目标类这里在设置一次
                if (shouldProxyTargetClass(beanClass, beanName)) {
                    proxyFactory.setProxyTargetClass(true);
                }
                else {
                    evaluateProxyInterfaces(beanClass, proxyFactory);
                }
            }
    
            //这里返回Advisor 所以仍然是返回BeanFactoryTransactionAttributeSourceAdvisor
            Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
            proxyFactory.addAdvisors(advisors);
            proxyFactory.setTargetSource(targetSource);
            customizeProxyFactory(proxyFactory);
    
            proxyFactory.setFrozen(this.freezeProxy);
            if (advisorsPreFiltered()) {
                proxyFactory.setPreFiltered(true);
            }
    
            // Use original ClassLoader if bean class not locally loaded in overriding class loader
            ClassLoader classLoader = getProxyClassLoader();
            if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
                classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
            }
            // 这里有两个逻辑,一根据需求创建AopProxy 二 调用getProxy 创建代理对象
            return proxyFactory.getProxy(classLoader);
        }
    

    调用AopProxy创建代理目标类,根据不同情况初始化不同AopProxy

    public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
        @Override
        public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
            // GraalVM Native Image 只支持 Dynamic proxy (java.lang.reflect.Proxy)
            if (!NativeDetector.inNativeImage() &&
                    (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
                Class<?> targetClass = config.getTargetClass();
                if (targetClass == null) {
                    throw new AopConfigException("TargetSource cannot determine target class: " +
                            "Either an interface or a target is required for proxy creation.");
                }
                if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                    return new JdkDynamicAopProxy(config);
                }
                return new ObjenesisCglibAopProxy(config);
            }
            else {
                return new JdkDynamicAopProxy(config);
            }
        }
    
        /**
         * Determine whether the supplied {@link AdvisedSupport} has only the
         * {@link org.springframework.aop.SpringProxy} interface specified
         * (or no proxy interfaces specified at all).
         */
        private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
            Class<?>[] ifcs = config.getProxiedInterfaces();
            return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
        }
    }
    

    其中JdkDynamicAopProxy 是通过InvocationHandler 接口实现,ObjenesisCglibAopProxy就是通过Cglib实现,这次只有看下Cglib如何创建动态对象的

        public Object getProxy(@Nullable ClassLoader classLoader) {
    
            try {
                Class<?> rootClass = this.advised.getTargetClass();
                Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");
    
                Class<?> proxySuperClass = rootClass;
                if (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
                    proxySuperClass = rootClass.getSuperclass();
                    Class<?>[] additionalInterfaces = rootClass.getInterfaces();
                    for (Class<?> additionalInterface : additionalInterfaces) {
                        this.advised.addInterface(additionalInterface);
                    }
                }
    
                // Validate the class, writing log messages as necessary.
                validateClassIfNecessary(proxySuperClass, classLoader);
    
                // Configure CGLIB Enhancer...
                //Cglib 核心就是通过Enhancer 对象去创建代理
                Enhancer enhancer = createEnhancer();
                if (classLoader != null) {
                    enhancer.setClassLoader(classLoader);
                    if (classLoader instanceof SmartClassLoader &&
                            ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                        enhancer.setUseCache(false);
                    }
                }
                enhancer.setSuperclass(proxySuperClass);
                enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
                enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
                enhancer.setStrategy(new ClassLoaderAwareGeneratorStrategy(classLoader));
                //这里将Spring 内置7MethodInterceptor 实现
                Callback[] callbacks = getCallbacks(rootClass);
                Class<?>[] types = new Class<?>[callbacks.length];
                for (int x = 0; x < types.length; x++) {
                    types[x] = callbacks[x].getClass();
                }
                // fixedInterceptorMap only populated at this point, after getCallbacks call above
                enhancer.setCallbackFilter(new ProxyCallbackFilter(
                        this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
                enhancer.setCallbackTypes(types);
    
                // Generate the proxy class and create a proxy instance.
                return createProxyClassAndInstance(enhancer, callbacks);
            }
    
        }
    

    Cglib样例

    编写一个简单Demo类,对方法进行前后增强。

    public class Demo {
    
        public void  call(){
            System.out.println("我就是目标类原始方法");
        }
    }
    

    编写拦截器

    public class CglibMethodInterceptor implements MethodInterceptor {
    
            /**
             * 通过在intercept 上重写方法达到通知增强逻辑
             * @param o 代表Cglib 生成的动态代理类 对象本身
             * @param method 代理类中被拦截的接口方法 Method 实例
             * @param objects 接口方法参数
             * @param methodProxy 用于调用父类真正的业务类方法。可以直接调用被代理类接口方法 原始方法
             * @return
             * @throws Throwable
             */
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("invoke before....");
                MonitorUtil.start();
                Object invoke = methodProxy.invokeSuper(o, objects);
                //Object invoke = method.invoke(o,objects); 这样会导致栈溢出
                System.out.println("invoken after");
                MonitorUtil.finish();
                return invoke;
            }
        }
    

    最后创建代理对象

        @Test
        public void cglibTest(){
            Enhancer enhancer = new Enhancer();
            enhancer.setClassLoader(this.getClass().getClassLoader());
            enhancer.setSuperclass(Demo.class);
            enhancer.setCallback(new CglibMethodInterceptor());
            Demo proxyInst = (Demo) enhancer.create();
            proxyInst.call();
        }
    

    执行结果

    invoke before....
    我就是目标类原始方法
    invoken after

    其实跟JDK动态代理写法差不多,都是通过在原始方法前后插入代码,达到增强。CGLIB支持多个MethodInterceptor,组成一个拦截器链,按照一定顺序执行intercept。这种方法有利于AOP结构和代理业务代码解耦。

    事务如何通过代理来实现的

    通过上面一个小例子,我们已经了解到实现代理逻辑核心就是getCallbacks(rootClass) 返回拦截器,内置拦截器有7种,事务实现类就是在CglibAopProxy.DynamicAdvisedInterceptor。

    private static class DynamicAdvisedInterceptor implements MethodInterceptor, Serializable {
    
            private final AdvisedSupport advised;
    
            public DynamicAdvisedInterceptor(AdvisedSupport advised) {
                this.advised = advised;
            }
    
            @Override
            @Nullable
            public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                Object oldProxy = null;
                boolean setProxyContext = false;
                Object target = null;
                TargetSource targetSource = this.advised.getTargetSource();
                try {
                    if (this.advised.exposeProxy) {
                        // Make invocation available if necessary.
                        oldProxy = AopContext.setCurrentProxy(proxy);
                        setProxyContext = true;
                    }
                    // Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...
                    target = targetSource.getTarget();
                    Class<?> targetClass = (target != null ? target.getClass() : null);
                    //这里会返回TransactionInterceptor 事务执行核心类
                    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
                    Object retVal;
                    // Check whether we only have one InvokerInterceptor: that is,
                    // no real advice, but just reflective invocation of the target.
                    if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) { //没有代理拦截器
                        // We can skip creating a MethodInvocation: just invoke the target directly.
                        // Note that the final invoker must be an InvokerInterceptor, so we know
                        // it does nothing but a reflective operation on the target, and no hot
                        // swapping or fancy proxying.
                        Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                        retVal = methodProxy.invoke(target, argsToUse);
                    }
                    else {
                        // We need to create a method invocation...  在这里执行事务
                        retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
                    }
                    retVal = processReturnType(proxy, target, method, retVal); //包装返回类型
                    return retVal;
                }
                finally {
                    if (target != null && !targetSource.isStatic()) {
                        targetSource.releaseTarget(target);
                    }
                    if (setProxyContext) {
                        // Restore old proxy.
                        AopContext.setCurrentProxy(oldProxy);
                    }
                }
            }
    

    这个内部类主要就是两个核心方法getInterceptorsAndDynamicInterceptionAdvice,从BeanFactoryTransactionAttributeSourceAdvisor.pointcut 返回MethodInterceptor 实现类TransactionInterceptor 并且使用InterceptorAndDynamicMethodMatcher 将返回MethodInterceptor、MethodMatcher 包装起来,下面会使用到的。
    将拦截器执行链作为构造器参数初始化CglibMethodInvocation,调用proceed 执行事务,proceed 会调用父类ReflectiveMethodInvocation.proceed,核心逻辑就在里面了。

        public Object proceed() throws Throwable {
            // We start with an index of -1 and increment early.
            // currentInterceptorIndex 默认是-1 相等表示拦截器链里面没有代理方法,直接执行原方法
            if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
                return invokeJoinpoint();
            }
            //从第一个开始执行
            Object interceptorOrInterceptionAdvice =
                    this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
            if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
                // Evaluate dynamic method matcher here: static part will already have
                // been evaluated and found to match.
                InterceptorAndDynamicMethodMatcher dm =
                        (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
                Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
                //dm 就是上面写到TransactionAnnotationParser
                if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
                    return dm.interceptor.invoke(this); //调用TransactionInterceptor.invoke
                }
                else {
                    // Dynamic matching failed.
                    // Skip this interceptor and invoke the next in the chain.
                    return proceed();
                }
            }
            else {
                // It's an interceptor, so we just invoke it: The pointcut will have
                // been evaluated statically before this object was constructed.
                return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
            }
        }
    
    

    这里使用递归方式执行调用链
    TransactionInterceptor 可以说是Spring事务执行器了,它负责执行事务,它自己本身没有任务事务实现代码,都是通TransactionManager 事务管理器来实现事务开始、回滚、提交。
    直接从TransactionInterceptor.invoke 开始分析

        public Object invoke(MethodInvocation invocation) throws Throwable {
            // Work out the target class: may be {@code null}.
            // The TransactionAttributeSource should be passed the target class
            // as well as the method, which may be from an interface.
            Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
    
            // Adapt to TransactionAspectSupport's invokeWithinTransaction...
            //这里调用父类TransactionAspectSupport.invokeWithinTransaction
            return invokeWithinTransaction(invocation.getMethod(), targetClass, new CoroutinesInvocationCallback() {
                @Override
                @Nullable
                public Object proceedWithInvocation() throws Throwable {
                    return invocation.proceed();
                }
                @Override
                public Object getTarget() {
                    return invocation.getThis();
                }
                @Override
                public Object[] getArguments() {
                    return invocation.getArguments();
                }
            });
        }
    

    invokeWithinTransaction 看方法吗方法命名就知道干什么的,执行事务方法。三个参数
    Method 要执行方法,主要是获取事务注解上属性
    Class 被代理Class,作业跟Method差不多
    InvocationCallback 被实现的class,主要用于执行代理方法。要知道Spring AOP是代理chain 方式执行,一个类不单止是被事务代理的,还有会因为其他业务被代理了,保证代理链能全部执行下去。

    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();
            //TransactionAttribute 是执行事务必须实体 包含很多重要信息 事务隔离级别、事务传播级别、异常回滚等
            final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);
            //获取TransactionManager 事务管理器,再平常开发中可以存在自己配置事务管理器情况,先读取@Transactional value 属性,
            //没有从transactionManagerBeanName 可以从配置文件指定
            //最后就是Spring默认事务实现
            final TransactionManager tm = determineTransactionManager(txAttr);
    
            if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {
                //这里是反应式事务 Mongdb NOSQL使用,这里略过
            }
    
            PlatformTransactionManager ptm = asPlatformTransactionManager(tm);
            final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
            
            // CallbackPreferringPlatformTransactionManager 是 PlatformTransactionManager  扩展接口提供在执行事务时暴露一个回调方法
            if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
                // Standard transaction demarcation with getTransaction and commit/rollback calls.
                // 获取正在执行的事务状态或者创建一个事务 TransactionInfo 事务状态 会记录事务执行,用于回滚
                TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
    
                Object retVal;
                try {
                    // This is an around advice: Invoke the next interceptor in the chain.
                    // This will normally result in a target object being invoked.
                    // invocation 就是被实现类,调用原始方法或者代理方法
                    // 其实这里就是around advice 环绕通知 前面开启事务,下面方法负责回滚或提交
                    retVal = invocation.proceedWithInvocation();
                }
                catch (Throwable ex) {
                    // target invocation exception
                    //处理业务异常,如果异常符合回滚,就会回滚否则就是commit
                    completeTransactionAfterThrowing(txInfo, ex);
                    throw ex;
                }
                finally {
                     // 在ThreadLocal 清除事务状态txInfo
                     //要知道所有事务都通过ThreadLocal 进行传递
                     //在正常或者异常情况下,清除线程绑定事务
                    cleanupTransactionInfo(txInfo);
                }
    
                //处理下返回值,使用了io.vavr.control.Try 来处理,没用过 略过下面
                if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
                    // Set rollback-only in case of Vavr failure matching our rollback rules...
                    TransactionStatus status = txInfo.getTransactionStatus();
                    if (status != null && txAttr != null) {
                        retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
                    }
                }
    
                //这个说的很明白 处理完返回值后再进行提交事务
                commitTransactionAfterReturning(txInfo);
                return retVal;
            }
    
            else { //这个是CallbackPreferringPlatformTransactionManager 执行事务方式
                   //跟上面处理差不多就是多了一个execute 方法,在回调函数去执行事务,相当于将事务执行交给调用者去实现
                Object result;
                final ThrowableHolder throwableHolder = new ThrowableHolder();
    
                // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in.
                try {
                    result = ((CallbackPreferringPlatformTransactionManager) ptm).execute(txAttr, status -> {
                        TransactionInfo txInfo = prepareTransactionInfo(ptm, txAttr, joinpointIdentification, status);
                        try {
                            Object retVal = invocation.proceedWithInvocation();
                            if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
                                // Set rollback-only in case of Vavr failure matching our rollback rules...
                                retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
                            }
                            return retVal;
                        }
                        catch (Throwable ex) {
                            if (txAttr.rollbackOn(ex)) {
                                // A RuntimeException: will lead to a rollback.
                                if (ex instanceof RuntimeException) {
                                    throw (RuntimeException) ex;
                                }
                                else {
                                    throw new ThrowableHolderException(ex);
                                }
                            }
                            else {
                                // A normal return value: will lead to a commit.
                                throwableHolder.throwable = ex;
                                return null;
                            }
                        }
                        finally {
                            cleanupTransactionInfo(txInfo);
                        }
                    });
                }
                catch (ThrowableHolderException ex) {
                    throw ex.getCause();
                }
                catch (TransactionSystemException ex2) {
                    if (throwableHolder.throwable != null) {
                        logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                        ex2.initApplicationException(throwableHolder.throwable);
                    }
                    throw ex2;
                }
                catch (Throwable ex2) {
                    if (throwableHolder.throwable != null) {
                        logger.error("Application exception overridden by commit exception", throwableHolder.throwable);
                    }
                    throw ex2;
                }
    
                // Check result state: It might indicate a Throwable to rethrow.
                if (throwableHolder.throwable != null) {
                    throw throwableHolder.throwable;
                }
                return result;
            }
        }
    

    总结

    image.png

    在这篇文章中我们简单学习了Spring初始化bean时,如何将bean创建成一个代理对象,并且使用Cglib技术创建一个代理bean,在结合事务管理器分析了代理如何去实现Spring事务的。使用一个小例子演示了Cglib代理如何实现的,方便理解Spring AOP代理是通过一个拦截器去实现的,一个对象的多个代理封装到调用链里面,执行方法时顺序执行,保证每一个代理与代理之间没有任何联系,相互独立。这次我还了解了Spring代理机制原理,通过Advisor实现类去解析Class、Method,通过PointcutAdvisor(匹配Class、Method)、IntroductionAdvisor (支持Class)是否需要生成代理对象。然后在通过专门代理工程去生成对应代理对象。
    我们简单了解事务实现,其实就是环绕通知实现而已,还了解到事务状态传递是通过ThreadLocal来实现的。

    相关文章

      网友评论

          本文标题:Spring事务实现原理

          本文链接:https://www.haomeiwen.com/subject/sfpairtx.html