关于java:Spring-Boot-事务源码探究

4次阅读

共计 2901 个字符,预计需要花费 8 分钟才能阅读完成。

首先申明:本次的 spring 版本 5.0.7.RELEASE,Spring boot 版本 2.0.3.RELEASE。

可能大多数同学晓得事务的执行提前条件是须要为指标类生成代理类,那么具体是什么机会被执行呢?

图 1

通过图 1 能够分明地看到

// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);

处开始执行,最终执行到 AbstractAutoProxyCreator.wrapIfNecessary() 办法:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) 
{
    
        // 获取 bean 的告诉器列表,该办法会依据 bean 的信息获取到对应的拦截器
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        // 如果告诉器列表不为空
        if (specificInterceptors != DO_NOT_PROXY) {this.advisedBeans.put(cacheKey, Boolean.TRUE);
            // 创立代理对象
            Object proxy = createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
}

其外围逻辑曾经在正文中有所体现,不再赘述~,紧接着对指标 bean 中的所有办法进行遍历,如果有办法匹配到拦截器列表的切点,则执行图 1 中创立代理对象。并且会将对应的告诉器放入到代理类中。以便在执行代理办法的时候进行拦挡。图 2 便是匹配切点的过程。

图 2

具体是怎么匹配的呢?上面看一个栗子:

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable {

    @Override
    public boolean matches(Method method, @Nullable Class<?> targetClass) {if (targetClass != null && TransactionalProxy.class.isAssignableFrom(targetClass)) {return false;}
        TransactionAttributeSource tas = getTransactionAttributeSource();
        // 重点在这里
        return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
    }
}

最终调用到 SpringTransactionAnnotationParser.parseTransactionAnnotation() 办法

public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {

    @Override
    @Nullable
    public TransactionAttribute parseTransactionAnnotation(AnnotatedElement ae) {
        // 获取 Transactional 注解
        AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(ae, Transactional.class, false, false);
        if (attributes != null) {
            // 解析 Transactional 注解配置项
            return parseTransactionAnnotation(attributes);
        }
        else {return null;}
    }
}

通过下面的代码块,咱们能够看到返回了 TransactionAttribute 类实例,这样一来

        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

就执行实现,到目前为止曾经拿到与之匹配的告诉器。接下来看代理对象的大抵构造:

图 3

图 3 外面的 TransactionInterceptor 实例,便是事务提交回滚的外围所在;那么,TransactionInterceptor 在什么时候被实例化呢?

图 4
图 5
图 6
图 7
下面四个图能够看到 spring boot 在创立 org.springframework.transaction.config.internalTransactionAdvisor 实例的会实例化 TransactionInterceptor。

那么问题又来了,internalTransactionAdvisor 什么时候被实例化呢?
答案是 objectMapperConfigurer 实例化的时候。

//1. Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);

//2.PostProcessorRegistrationDelegate 类
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
        // 获取 BeanPostProcessor 类型的 Bean 处理器蕴含 objectMapperConfigurer
        String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
        for (String ppName : postProcessorNames) {if (!processedBeans.contains(ppName)) {
              currentRegistryProcessors.add(
              // 实例化 objectMapperConfigurer
              beanFactory.getBean(ppName,BeanDefinitionRegistryPostProcessor.class));
              processedBeans.add(ppName);
              reiterate = true;
          }
        }
}
正文完
 0