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

首先申明:本次的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;
          }
        }
}

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理