锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

Spring源码之事务处理

时间:2022-08-22 22:00:01 连接器主线对射光电开关传感器感应开关ex

一、spring事务源码

1. 注解

@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Import(TransactionManagementConfigurationSelector.class) public @interface EnableTransactionManagement { 
           /** * 是否采用CGLIB进行代理 */  boolean proxyTargetClass() default false;   /** * 使用代理模型JDK作为通知模型 */  AdviceMode mode() default AdviceMode.PROXY;   /** * 优先级 */  int order() default Ordered.LOWEST_PRECEDENCE;  } 

2. 注册类

2.1 selectImports()

TransactionManagementConfigurationSelector : 导入自动代理的配置对象,会注入 org.springframework.aop.config.internalAutoProxyCreator 如果处理器已经存在,将根据以下优先级设置

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> { 
           /** * 根据通知模型返回相应的代理配置类型 */  @Override  protected String[] selectImports(AdviceMode adviceMode) { 
           switch (adviceMode) { 
            case PROXY:                 ////注册自动代理扫描     return new String[] { 
        AutoProxyRegistrar.class.getName(
       
        )
        , 
        //注入事务代理配置对象 
        ProxyTransactionManagementConfiguration
        .
        class
        .
        getName
        (
        )
        }
        ; 
        case ASPECTJ
        : 
        //返回 Aspectj代理对象方式 
        return 
        new 
        String
        [
        ] 
        { 
         
        determineTransactionAspectClass
        (
        )
        }
        ; 
        default
        : 
        return 
        null
        ; 
        } 
        } 
        private 
        String 
        determineTransactionAspectClass
        (
        ) 
        { 
          
        return 
        (
        ClassUtils
        .
        isPresent
        (
        "javax.transaction.Transactional"
        , 
        getClass
        (
        )
        .
        getClassLoader
        (
        )
        ) 
        ? 
        TransactionManagementConfigUtils
        .JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME 
        : 
        TransactionManagementConfigUtils
        .TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME
        )
        ; 
        } 
        } 
       

2.2 registerOrEscalateApcAsRequired()

注入事务创建器,如果已经存在了代理创建器的话,会根据优先级进行注入;

private static BeanDefinition registerOrEscalateApcAsRequired(
			Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) { 
        

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		//首先判断是否有 org.springframework.aop.config.internalAutoProxyCreator bean
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) { 
        
			//获取到 org.springframework.aop.config.internalAutoProxyCreator
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			//判断类型是否跟当前注册的一样,如果不一样需要根据优先级进行设置
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) { 
        
				/** * 设置优先级,通过注解注入切面器的优先级最高,事务优先级最低,aop切面的最高 * InfrastructureAdvisorAutoProxyCreator * AspectJAwareAdvisorAutoProxyCreator * AnnotationAwareAspectJAutoProxyCreator */
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) { 
        
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}
		//创建bean定义注册到容器中
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

在这里插入图片描述

3. 配置类

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.<Integer>getNumber("order"));
		}
		return advisor;
	}

	/** * 创建直接属性资源对象,其中主要的目的就是用于 Pointcut用来匹配方法注解 * 其中注解的匹配会根据依赖路径下面是否包含 javax.transaction.Transactional, javax.ejb.TransactionAttribute 来创建注解解析器 * 默认支持 SpringTransactionAnnotationParser解析器,用于匹配spring中的 @Transactional * SpringTransactionAnnotationParser、JtaTransactionAnnotationParser、Ejb3TransactionAnnotationParser */
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() { 
        
		return new AnnotationTransactionAttributeSource();
	}

	/** * 创建一个事务拦截器(Advice) * @param transactionAttributeSource * @return */
	@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;
	}

}

当前抽象类实现了接口 ImportAware 这个接口会在 ConfigurationClassPostProcessor 中注入一个名称 ConfigurationClassPostProcessor.class.getName() + “.importRegistry”; 注册工厂,会返回 ConfigurationClassPostProcessor 对象中的 importStack 属性,当前属性用于记录当前类是由谁进行导入的;

@Configuration
public abstract class AbstractTransactionManagementConfiguration implements ImportAware { 
        

	@Nullable
	protected AnnotationAttributes enableTx;

	@Nullable
	protected TransactionManager txManager;


	/** * 在 ConfigurationClassPostProcessor 中会注入一个 ImportAwareBeanPostProcessor 在bean创建完之后会处理 ImportAware的注解 * 获取到当前bean对象是由谁进行注入的元数据 */
	@Override
	public void setImportMetadata(AnnotationMetadata importMetadata) { 
        
		this.enableTx = AnnotationAttributes.fromMap(
				importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName()));
		if (this.enableTx == null) { 
        
			throw new IllegalArgumentException(
					"@EnableTransactionManagement is not present on importing class " + importMetadata.getClassName());
		}
	}

	/** * 自动注入容器中 实现了 TransactionManagementConfigurer 可以用于获取事务管理器 */
	@Autowired(required = false)
	void setConfigurers(Collection<TransactionManagementConfigurer> configurers) { 
        
		if (CollectionUtils.isEmpty(configurers)) { 
        
			return;
		}
		if (configurers.size() > 1) { 
        
			throw new IllegalStateException("Only one TransactionManagementConfigurer may exist");
		}
		TransactionManagementConfigurer configurer = configurers.iterator().next();
		this.txManager = configurer.annotationDrivenTransactionManager();
	}


	/** * 设置事务事件工厂,默认支持 TransactionalEventListener 注解的方法 * @return */
	@Bean(name = TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public static TransactionalEventListenerFactory transactionalEventListenerFactory() { 
        
		return new TransactionalEventListenerFactory();
	}

}

4. Advisor

上面的配置类可以看到spring注入了一个 BeanFactoryTransactionAttributeSourceAdvisor 增强器,当前增强器中返回的比较重要的属性:

  • advice: TransactionInterceptor;用于方法拦截的通知
  • transactionAttributeSource:TransactionAttributeSource;用于匹配方法中是否有 @Transactional
  • pointcut:TransactionAttributeSourcePointcut;抽象类,复写了getTransactionAttributeSource() 方法,并且返回 transactionAttributeSource属性

在aop的源码中我们看到,在spring找出所有 Advisor 之后会调用其中 Pointcut 里面的 classFilter 属性进行匹配,然后再调用 methodMatcher 进行方法匹配。

spring先匹配类,创建Pointcut 时,默认创建了 TransactionAttributeSourceClassFilter 类型的过滤器;可以看到该类型是一个内部类,先匹配是否是一些基础类型,然后再通过上面复写的方法获取到 transactionAttributeSource 来进行匹配,配置类中注入的类型是 AnnotationTransactionAttributeSource

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable { 
        

	protected TransactionAttributeSourcePointcut() { 
        
		setClassFilter(new TransactionAttributeSourceClassFilter());
	}
}

-------------------------------------分割线--------------------------------------
    /** * 通过Pointcut调用classFilter进行匹配时调用 */
    private class TransactionAttributeSourceClassFilter implements ClassFilter { 
        

        @Override
        public boolean matches(Class<?> clazz) { 
        
            if (TransactionalProxy.class.isAssignableFrom(clazz) ||
                TransactionManager.class.isAssignableFrom(clazz) ||
                PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) { 
        
                return false;
            }
            //获取到 transactionAttributeSource,由于上面已经复写了
            TransactionAttributeSource tas = getTransactionAttributeSource();
            return (tas == null || tas.isCandidateClass(clazz));
        }
    }
    /** * org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#isCandidateClass * 其中遍历的 annotationParsers 是默认创建的注解解析器 * 默认会构建:SpringTransactionAnnotationParser */
    public boolean isCandidateClass(Class<?> targetClass) { 
        
		for (TransactionAnnotationParser parser : this.annotationParsers) { 
        
            //当前判断的方法通过 AnnotationUtils.isCandidateClass(targetClass, Transactional.class); 进行匹配,只判断了一下注解类型和目标class的前缀,就返回了true
			if (parser.isCandidateClass(targetClass)) { 
        
				return true;
			}
		}
		return false;
	}

看上面的依赖图能够发现 TransactionAttributeSourcePointcut 本身类就实现了 MethodMatcher 类型,获取方法匹配时默认就会返回本身,所以调用方法匹配时,会调用到自己的 matches()

abstract class TransactionAttributeSourcePointcut extends StaticMethodMatcherPointcut implements Serializable { 
        

	@Override
	public boolean matches(Method method, Class<?> targetClass) { 
        
		TransactionAttributeSource tas = getTransactionAttributeSource();
        // 调用AnnotationTransactionAttributeSource中的 getTransactionAttribute();但是 tas中并没有这个方法,当前方法在父类中 AbstractFallbackTransactionAttributeSource
		return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);
	}
}
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) { 
        
		if (method.getDeclaringClass() == Object.class) { 
        
			return null;
		}
    	//获取方法的缓存key对象
		Object cacheKey = getCacheKey(method, targetClass);
       //缓存中是否存在缓存的对象
		TransactionAttribute cached = this.attributeCache.get(cacheKey);
		if (cached != null) { 
        
            //获取到缓存后查看是否是默认的类型
			if (cached == NULL_TRANSACTION_ATTRIBUTE) { 
        
				return null;
			}
			else { 
        
				return cached;
			}
		}
		else { 
        
            //这里会通过方法去解析注解上面是否有 @Transactional 注解,并且把注解解析成 RuleBasedTransactionAttribute 对象进行返回
			TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);
			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);
				}
				if (logger.isTraceEnabled()) { 
        
					logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
				}
                //存入缓存中
				this.attributeCache.put(cacheKey, txAttr);
			}
			return txAttr;
		}
	}
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) { 
        
		if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) { 
        
			return null;
		}
		//这里获取到最原始的方法;会判断方法是否是复写的方法,如果是复写的方法,获取到接口上的方法等。获取到方法后,会将方法进行缓存上
		Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);

		//获取到方法中是否具有 @Transactional 注解,如果有注解,将注解中的属性解析成 RuleBasedTransactionAttribute 对象
		TransactionAttribute txAttr = findTransactionAttribute(specificMethod);
		if (txAttr != null) { 
        
			return txAttr;
		}
		//如果方法上面获取不到 @Transactional 会尝试通过类进行获取
		txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
		if (txAttr != null && ClassUtils.isUserLevelMethod(method)) { 
        
			return txAttr;
		}

		//如果解析出的方法,跟传入的方法不一样,再尝试从原方法中获取
		if (specificMethod != method) { 
        
			txAttr = findTransactionAttribute(method);
			if (txAttr != null) { 
        
				return txAttr;
			}
			//再尝试从原方法定义的class中获取
			txAttr = findTransactionAttribute(method.getDeclaringClass());
			if (txAttr != null && ClassUtils.isUserLevelMethod(method)) { 
        
				return txAttr;
			}
		}

		return null;
	}

5. Advice

org.springframework.transaction.interceptor.TransactionInterceptor : 目标方法拦截器

public Object invoke(MethodInvocation invocation) throws Throwable { 
        
		//计算出目标类
		Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
		//调用父类 TransactionAspectSupport 中的方法,并且设置一个回调方法,这个回调方法直接调用本体方法
		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();
			}
		});
	}

5.1 invokeWithinTransaction()

protected Object invokeWithinTransaction(Method method 

相关文章