乐趣区

关于spring:Spring事务实现原理

代理对象在哪里创立

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

总结

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

退出移动版