spring源码分析-事务管理

当需要使用事务时我们会在xml配置文件中配置

<!--使用注解事务 -->
<tx:annotation-driven  transaction-manager="transactionManager" />

跟Aop一样,当我们引入spring-tx 依赖时该jar包下有一个spring.handlers文件,文件中有如下配置

http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler

当我们容器在解析xml配置文件时会解析到http\://www.springframework.org/schema/tx该命名空间,所以会使用文件中配置的org.springframework.transaction.config.TxNamespaceHandler类解析<tx:annotation-driven transaction-manager="transactionManager" />

该handle在初始化时又会注册下面几个parse

@Override
public void init() {
   registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
   registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
   registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}

所以在解析到annotation-driven时会用AnnotationDrivenBeanDefinitionParser,下面我们来看下AnnotationDrivenBeanDefinitionParser到底是怎么处理注解事务的

@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
    //注册transactionalEventListenerFactory到beanFactory中
   registerTransactionalEventListenerFactory(parserContext);
   String mode = element.getAttribute("mode");
    //判断配置的model是aspectj还是proxy如果是aspectj就用aspectj的处理方法如果是proxy就使用proxy
   if ("aspectj".equals(mode)) {
      // mode="aspectj"
      registerTransactionAspect(element, parserContext);
      if (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader())) {
         registerJtaTransactionAspect(element, parserContext);
      }
   }
   else {
      // mode="proxy"
      AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
   }
   return null;
}
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
    //注册InfrastructureAdvisorAutoProxyCreator
   AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);

   String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
   if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
      Object eleSource = parserContext.extractSource(element);

      // Create the TransactionAttributeSource definition.
      RootBeanDefinition sourceDef = new RootBeanDefinition(
            "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
      sourceDef.setSource(eleSource);
      sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
      String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

      // Create the TransactionInterceptor definition.
      //TransactionInterceptor
      RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
      interceptorDef.setSource(eleSource);
      interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
      //注册事务管理器,会注入到该TransactionInterceptor中
      registerTransactionManager(element, interceptorDef);
      interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
      String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);

      // Create the TransactionAttributeSourceAdvisor definition.
       //创建事务advisor 该类会判断对象是否开启了事务,实际判断类最后是调用上面的					      AnnotationTransactionAttributeSource
      RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
      advisorDef.setSource(eleSource);
      advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
       //添加上面的AnnotationTransactionAttributeSource依赖
      advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
       //添加transactionInterceptor依赖
      advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
      if (element.hasAttribute("order")) {
         advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
      }
      parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);

      CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
      compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
      compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
      compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
      parserContext.registerComponent(compositeDef);
   }
}

上面代码表示了当我们是model=‘proxy’的时候会注册InfrastructureAdvisorAutoProxyCreator到spring,该类又是继承了AbstractAdvisorAutoProxyCreator,所以在bean初始化完的时候会调用AbstractAdvisorAutoProxyCreator类的postProcessAfterInitialization方法:

	/**
	 * Create a proxy with the configured interceptors if the bean is
	 * identified as one to proxy by the subclass.
	 * @see #getAdvicesAndAdvisorsForBean
	 */
	@Override
	public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
		if (bean != null) {
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}	

该方法会调用wrapIfNecessary:

/**
 * Wrap the given bean if necessary, i.e. if it is eligible for being proxied.
 * @param bean the raw bean instance
 * @param beanName the name of the bean
 * @param cacheKey the cache key for metadata access
 * @return a proxy wrapping the bean, or the raw bean instance as-is
 */
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
   if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
      return 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创建代理对象,所以这里返回的就是bean的代理类了
      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;
}

wrapIfNecessary方法会去获得spring beanFacotry中的所有Advisor接口实现类,还记得上面parse的时候注入的

BeanFactoryTransactionAttributeSourceAdvisor类吗,该类实现了Advisor接口

 

/**
 * Find all eligible Advisors for auto-proxying this class.
 * @param beanClass the clazz to find advisors for
 * @param beanName the name of the currently proxied bean
 * @return the empty List, not {@code null},
 * if there are no pointcuts or interceptors
 * @see #findCandidateAdvisors
 * @see #sortAdvisors
 * @see #extendAdvisors
 */
//上面的getAdvicesAndAdvisorsForBean方法最后会调用该方法
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    //因为上面注入了BeanFactoryTransactionAttributeSourceAdvisor类,所以这里会取到BeanFactoryTransactionAttributeSourceAdvisor
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
    //这里会返回beanClass符合的Advisors,就是BeanFactoryTransactionAttributeSourceAdvisor
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}

上面的findAdvisorsThatCanApply方法最终会调用到下面这个canApply方法:

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
   if (advisor instanceof IntroductionAdvisor) {
      return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
   }
    //因为BeanFactoryTransactionAttributeSourceAdvisor是实现了PointcutAdvisor的所以回进入下面的canApply方法
   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;
   }
}

下面是BeanFactoryTransactionAttributeSourceAdvisor类的类定义:

@SuppressWarnings("serial")
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {

   @Nullable
   private TransactionAttributeSource transactionAttributeSource;

       private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {
          @Override
          @Nullable
          protected TransactionAttributeSource getTransactionAttributeSource() {
             return transactionAttributeSource;
          }
       };
   ...
   }

因为BeanFactoryTransactionAttributeSourceAdvisor的pointcut是TransactionAttributeSourcePointcut类所以下面canApply的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;
   }

   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)) {
      classes.add(ClassUtils.getUserClass(targetClass));
   }
   classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

   for (Class<?> clazz : classes) {
      Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
       //因为该pointcut是TransactionAttributeSourcePointcut所以会调用其下的matches方法
      for (Method method : methods) {
         if (introductionAwareMethodMatcher != null ?
               introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
               methodMatcher.matches(method, targetClass)) {
            return true;
         }
      }
   }

   return false;
}
public boolean matches(Method method, Class<?> targetClass) {
   if (TransactionalProxy.class.isAssignableFrom(targetClass) ||
         PlatformTransactionManager.class.isAssignableFrom(targetClass) ||
         PersistenceExceptionTranslator.class.isAssignableFrom(targetClass)) {
      return false;
   }
    //最后是调用到之前注入的transactionAttributeSource
   TransactionAttributeSource tas = getTransactionAttributeSource();
   return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
}

最后调用到下面的方法

public TransactionAttribute parseTransactionAnnotation(AnnotatedElement element) {
    //获取注解了Transactional的属性如:rollbackFor、timeout这些
   AnnotationAttributes attributes = AnnotatedElementUtils.findMergedAnnotationAttributes(
         element, Transactional.class, false, false);
   if (attributes != null) {
      return parseTransactionAnnotation(attributes);
   }
   else {
      return null;
   }
}

因为代理对象调用方法的时候其实是会调用上面BeanFactoryTransactionAttributeSourceAdvisor注入的TransactionInterceptor类的invoke方法,所以最后在这里提交事务或回滚事务:

@Override
@Nullable
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, invocation::proceed);
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值