spring 事务源码阅读

开启事务

使用@EnableTransactionManagement注解开启事务

该注解会引入TransactionManagementConfigurationSelector类,然后该类导入两个类AutoProxyRegistrar和ProxyTransactionManagementConfiguration。

1、添加bean后置处理器

AutoProxyRegistrar类的作用是注册InfrastructureAdvisorAutoProxyCreator类,InfrastructureAdvisorAutoProxyCreator是Spring中实现AOP代理的关键组件,它会扫描所有的Advisor(通知器),并将其与BeanFactory中的Bean进行匹配,以决定是否需要为该Bean创建AOP代理。

InfrastructureAdvisorAutoProxyCreator 继承AbstractAdvisorAutoProxyCreator 继承AbstractAutoProxyCreator,实现SmartInstantiationAwareBeanPostProcessor和BeanFactoryAware接口。

是一个bean后置处理器

public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
   @Nullable
   private ConfigurableListableBeanFactory beanFactory;
   @Override
   protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
      super.initBeanFactory(beanFactory);
      this.beanFactory = beanFactory;
   }
   @Override
   protected boolean isEligibleAdvisorBean(String beanName) {
      return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&
            this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);
   }

}

代理的创建在上一篇AOP源码阅读中有说过就是在后置处理器的after方法寻找合适的advisor进行创建代理。上面的源码看到InfrastructureAdvisorAutoProxyCreator只是重写了initBeanFactory方法用来获取beanfacotry和isEligibleAdvisorBean方法用来判断是否是合适的bean。

2、引入Advisor

TransactionManagementConfigurationSelector引入的另一个类是ProxyTransactionManagementConfiguration,该类代码也不多,如下

@Configuration(proxyBeanMethods = false)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

   @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
   public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
         TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {

      BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
      advisor.setTransactionAttributeSource(transactionAttributeSource);
      advisor.setAdvice(transactionInterceptor);
      if (this.enableTx != null) {
         advisor.setOrder(this.enableTx.getNumber("order"));
      }
      return advisor;
   }

   @Bean
   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
   public TransactionAttributeSource transactionAttributeSource() {
      return new AnnotationTransactionAttributeSource();
   }

   @Bean
   @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
   public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
      TransactionInterceptor interceptor = new TransactionInterceptor();
      interceptor.setTransactionAttributeSource(transactionAttributeSource);
      if (this.txManager != null) {
         interceptor.setTransactionManager(this.txManager);
      }
      return interceptor;
   }

}

ProxyTransactionManagementConfiguration类主要引入BeanFactoryTransactionAttributeSourceAdvisor通知类。并为其TransactionAttributeSource和TransactionInterceptor两个属性赋值。该类实现了Advisor接口,是一个PointcutAdvisor类型的Advisor,用来匹配@Transaction注解。具体如何匹配下面结合源码说。

代理创建

1、获取所有Advisor

在AbstractAutoProxyCreator的后置出来器afater方法里还是会调用wrapIfNecessary(bean, beanName, cacheKey)来判断当前bean是否需要包装代理。然后会调用getAdvicesAndAdvisorsForBean(bean.getClass(), beanName)方法尝试获取适用于该bean的advice。这个方法在AbstractAdvisorAutoProxyCreator 中实现

AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

protected Object[] getAdvicesAndAdvisorsForBean(
      Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
   //获取符合条件的advisor
   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
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
      //获取适用于当前bean的advisor
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

findCandidateAdvisors()方法还是在该类中实现,使用了一个BeanFactoryAdvisorRetrievalHelper工具类进行获取Advisor

AbstractAdvisorAutoProxyCreator#findCandidateAdvisors

protected List<Advisor> findCandidateAdvisors() {
     return this.advisorRetrievalHelper.findAdvisorBeans();
}

BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans

public List<Advisor> findAdvisorBeans() {
   String[] advisorNames = this.cachedAdvisorBeanNames;
   if (advisorNames == null) {
      //从beanfacotry总获取所有的Advisor
      advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
            this.beanFactory, Advisor.class, true, false);
      this.cachedAdvisorBeanNames = advisorNames;
   }
   if (advisorNames.length == 0) {
      return new ArrayList<>();
   }

   List<Advisor> advisors = new ArrayList<>();
   for (String name : advisorNames) {
      if (isEligibleBean(name)) {//调用isEligibleBean判断bean是否满足基本条件
         advisors.add(this.beanFactory.getBean(name, Advisor.class));
      }
   }
   return advisors;
}

这里看到Advisor的获取是直接从beanFacotry中查找Advisor.class类型的beanDef,这样就能找到我们最开始通过import导入的BeanFactoryTransactionAttributeSourceAdvisor。这和上一篇说的AOP的Aspect方式有一些区别(扫描所有的bean,反射解析@Aspect注解)。

2、寻找匹配的Advisor

找到所有的Advisor后下一步就是逐个判断是否适用于当前bean

protected List<Advisor> findAdvisorsThatCanApply(
      List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

   ProxyCreationContext.setCurrentProxiedBeanName(beanName);
   try {
      return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
   }
   finally {
      ProxyCreationContext.setCurrentProxiedBeanName(null);
   }
}

AopUtils#findAdvisorsThatCanApply

public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
   if (candidateAdvisors.isEmpty()) {
      return candidateAdvisors;
   }
   List<Advisor> eligibleAdvisors = new ArrayList<>();
   //这里不是IntroductionAdvisor类型的不会进入循环
   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;
      }
      //进入canApply方法判断
      if (canApply(candidate, clazz, hasIntroductions)) {
         eligibleAdvisors.add(candidate);
      }
   }
   return eligibleAdvisors;
}

AopUtils#canApply

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 pca = (PointcutAdvisor) advisor;
      return canApply(pca.getPointcut(), targetClass, hasIntroductions);
   }
   else {
      // It doesn't have a pointcut so we assume it applies.
      return true;
   }
}

最开始说过我们引入的advisor是一个PointcutAdvisor类型。所以会进入第二个if分支。拿出pointcut进行匹配。这里的advisor是BeanFactoryTransactionAttributeSourceAdvisor实例,器pointcut是TransactionAttributeSourcePointcut类型实例。下一个重载canApply方法主要匹配逻辑是下面代码

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
   //...
   //这里返回的matcher还是TransactionAttributeSourcePointcut本身
   MethodMatcher methodMatcher = pc.getMethodMatcher();
   for (Class<?> clazz : classes) {
     //拿出class所有方法与matcher进行匹配
      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;
}

主要的匹配逻辑是methodMatcher.matches,也就是

TransactionAttributeSourcePointcut#matches

public boolean matches(Method method, Class<?> targetClass) {
   //获取TransactionAttributeSource,这是最开始在引入Advisor设置的
   TransactionAttributeSource tas = getTransactionAttributeSource();
   return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

这里TransactionAttributeSource是最开始引入由ProxyTransactionManagementConfiguration类内部设置的,其实例类型是AnnotationTransactionAttributeSource ,该类继承 AbstractFallbackTransactionAttributeSource。getTransactionAttribute()方法在其父类中

AbstractFallbackTransactionAttributeSource#getTransactionAttribute

public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   if (method.getDeclaringClass() == Object.class) {//Object类方法跳过
      return null;
   }

   // First, see if we have a cached value.
   Object cacheKey = getCacheKey(method, targetClass);
   TransactionAttribute cached = this.attributeCache.get(cacheKey);
   if (cached != null) {//先从缓存获取,如果没有解析
      // Value will either be canonical value indicating there is no transaction attribute,
      // or an actual transaction attribute.
      if (cached == NULL_TRANSACTION_ATTRIBUTE) {
         return null;
      }
      else {
         return cached;
      }
   }
   else {
      // 解析当前方法事务属性
      TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
      // Put it in the cache.
      if (txAttr == null) {
         this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);
      }
      else {
         String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
         if (txAttr instanceof DefaultTransactionAttribute) {
            DefaultTransactionAttribute dta = (DefaultTransactionAttribute) txAttr;
            dta.setDescriptor(methodIdentification);
            dta.resolveAttributeStrings(this.embeddedValueResolver);
         }

         this.attributeCache.put(cacheKey, txAttr);
      }
      return txAttr;
   }
}

解析实际方法是computeTransactionAttribute()

protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
   //step1 判断方法必须是public方法
   if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
      return null;
   }

   // The method may be on an interface, but we need attributes from the target class.
   // If the target class is null, the method will be unchanged.
   Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

   //step2 解析方法事务属性
   TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
   if (txAttr != null) {
      return txAttr;
   }

   // Second try is the transaction attribute on the target class.
   txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
   if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
      return txAttr;
   }

   if (specificMethod != method) {
      // Fallback is to look at the original method.
      txAttr = findTransactionAttribute(method);
      if (txAttr != null) {
         return txAttr;
      }
      // Last fallback is the class of the original method.
      txAttr = findTransactionAttribute(method.getDeclaringClass());
      if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
         return txAttr;
      }
   }

   return null;
}

step2处findTransactionAttribute()方法解析事务属性,该方法是AnnotationTransactionAttributeSource类实现,其调用determineTransactionAttribute(method)方法。

AnnotationTransactionAttributeSource#determineTransactionAttribute

protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
   for (TransactionAnnotationParser parser : this.annotationParsers) {
      TransactionAttribute attr = parser.parseTransactionAnnotation(element);
      if (attr != null) {
         return attr;
      }
   }
   return null;
}

这里拿出所有的annotationParsers进行解析方法是否定义事务。annotationParsers是在AnnotationTransactionAttributeSource的构造方法初始化,这里有两个SpringTransactionAnnotationParser和JtaTransactionAnnotationParser。我们主要看SpringTransactionAnnotationParser。

SpringTransactionAnnotationParser#parseTransactionAnnotation

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
   AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
         element, Transactional.class, false, false);
   if (attributes != null) {
      return parseTransactionAnnotation(attributes);
   }
   else {
      return null;
   }
}

终于看到熟悉的Transactional注解了,也不往方法里面看了。这里就是解析@Transactional注解配置的事务属性。

3、事务管理

代理创建和AOP过程一致,这里还是以JDK代理类为例。代理对象是JdkDynamicAopProxy。原方法的执行会首先进入JdkDynamicAopProxy.invoke方法。

这里还是从invoke的获取拦截器链开始

List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

最后会调到

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
   List<MethodInterceptor> interceptors = new ArrayList<>(3);
   Advice advice = advisor.getAdvice();
   if (advice instanceof MethodInterceptor) {//会走这里
      interceptors.add((MethodInterceptor) advice);
   }
   for (AdvisorAdapter adapter : this.adapters) {//这是Aspect的情况
      if (adapter.supportsAdvice(advice)) {
         interceptors.add(adapter.getInterceptor(advisor));
      }
   }
   if (interceptors.isEmpty()) {
      throw new UnknownAdviceTypeException(advisor.getAdvice());
   }
   return interceptors.toArray(new MethodInterceptor[0]);
}

这里要回到开始ProxyTransactionManagementConfiguration引入Advisor引入的地方

public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
      TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {

   BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
   advisor.setTransactionAttributeSource(transactionAttributeSource);
   //设置的advisor是TransactionInterceptor类型
   advisor.setAdvice(transactionInterceptor);
   if (this.enableTx != null) {
      advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
   }
   return advisor;
}

所以最后会调用TransactionInterceptor的invoke方法

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...
   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方法完成。

总结

开启事务为我们引入了两个重要的

1、BeanFactoryTransactionAttributeSourceAdvisor事务Advisor。设置两个属性TransactionInterceptor用来代理管理事务,TransactionAttributeSource用来匹配事务方法。

1、InfrastructureAdvisorAutoProxyCreator是bean后置处理器,用来判断当前bean是否需要代理。会拿出第一步引入的事务Advisor,与当前bean的所有方法进行匹配看是否有@Transaction注解。有就创建代理,最后使用BeanFactoryTransactionAttributeSourceAdvisor中设置的TransactionInterceptor拦截器进行事务管理。

整理流程
spring 事务源码阅读_第1张图片

你可能感兴趣的:(spring,spring,java,数据库)