声明式事务原理——1. @EnableTransactionManagement

@EnableTransactionManagement

可以看出这个注解的主要作用是导入TransactionManagementConfigurationSelector

@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
	boolean proxyTargetClass() default false;
	AdviceMode mode() default AdviceMode.PROXY;
	int order() default Ordered.LOWEST_PRECEDENCE;
}

TransactionManagementConfigurationSelector

可以看出TransactionManagementConfigurationSelector继承自ImportSelector接口,说明此类的作用是导入相关bean。
TransactionManagementConfigurationSelector

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			// 默认是 PROXY 类型,那就以它为例。导入了两个类。
			case PROXY:
				return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
			default:
				return null;
		}
	}
}

AutoProxyRegistrar

AutoProxyRegistrar继承自ImportBeanDefinitionRegistrar,说明它的作用也是导入相关bean。

public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
		Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
		for (String annType : annTypes) {
			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
			if (candidate == null) {
				continue;
			}
			Object mode = candidate.get("mode");
			Object proxyTargetClass = candidate.get("proxyTargetClass");
			if (mode != null && proxyTargetClass != null && AdviceMode.class == mode.getClass() &&
					Boolean.class == proxyTargetClass.getClass()) {
				candidateFound = true;
				if (mode == AdviceMode.PROXY) {
					
					// 就是这行起关键作用了
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
					if ((Boolean) proxyTargetClass) {
						AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
						return;
					}
				}
			}
		}
		// log...
	}
}

AopConfigUtils#registerAutoProxyCreatorIfNecessary

	public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
		return registerAutoProxyCreatorIfNecessary(registry, null);
	}

registerAutoProxyCreatorIfNecessary

	public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
	// 传入 InfrastructureAdvisorAutoProxyCreator 类型。
		return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
	}

registerOrEscalateApcAsRequired

	public static final String AUTO_PROXY_CREATOR_BEAN_NAME =
		"org.springframework.aop.config.internalAutoProxyCreator";
	private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
		// ... 
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		// ... 把 InfrastructureAdvisorAutoProxyCreator 注册进 IOC,bean id 是 AUTO_PROXY_CREATOR_BEAN_NAME
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

这段代码和 《AOP 原理——1. @EnableAspectJAutoProxy》 文章中的一样,那篇文章的registerOrEscalateApcAsRequired和这篇文章是同一个方法,但是为了避免冲突,是有一个优先级的。

	private static final List<Class<?>> APC_PRIORITY_LIST = new ArrayList<>(3);
	static {
		// 优先级从下往上
		// Set up the escalation list...
		APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
		// 《AOP 原理——1. @EnableAspectJAutoProxy》文章中注册的便是这个优先级最高的类
		APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
	}

所以起关键作用的是InfrastructureAdvisorAutoProxyCreator类。

InfrastructureAdvisorAutoProxyCreator

可以看出它实现了BeanPostProcessor,所以它是依靠BeanPostProcessorInstantiationAwareBeanPostProcessor创建增强的动态代理对象的。和 《AOP 原理——1. @EnableAspectJAutoProxy 》文章中的AnnotationAwareAspectJAutoProxyCreator原理差不多。就是AOP的那一套,就不多说了,有关AOP创建动态代理对象的原理见 《AOP原理——2. AbstractAutoProxyCreator 创建动态代理对象》 。
InfrastructureAdvisorAutoProxyCreator


ProxyTransactionManagementConfiguration

@Transactional的配置和执行

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		advisor.setAdvice(transactionInterceptor());
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
		// @Transactional 属性的处理
		return new AnnotationTransactionAttributeSource();
	}

	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionInterceptor transactionInterceptor() {
		// 拦截的信息
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource());
		if (this.txManager != null) {
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}

属性处理:
AnnotationTransactionAttributeSource
事物增强器要用事务注解的信息,适用这个类解析事务的注解。

	// 构造方法
	public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
		this.publicMethodsOnly = publicMethodsOnly;
		this.annotationParsers = new LinkedHashSet<>(2);
		// 以 SpringTransactionAnnotationParser 为例
		this.annotationParsers.add(new SpringTransactionAnnotationParser());
		if (jta12Present) {
			this.annotationParsers.add(new JtaTransactionAnnotationParser());
		}
		if (ejb3Present) {
			this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
		}
	}

SpringTransactionAnnotationParser#parseTransactionAnnotation
这些属性的解析都有了。

	protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
		Propagation propagation = attributes.getEnum("propagation");
		rbta.setPropagationBehavior(propagation.value());
		Isolation isolation = attributes.getEnum("isolation");
		rbta.setIsolationLevel(isolation.value());
		rbta.setTimeout(attributes.getNumber("timeout").intValue());
		rbta.setReadOnly(attributes.getBoolean("readOnly"));
		rbta.setQualifier(attributes.getString("value"));
		ArrayList<RollbackRuleAttribute> rollBackRules = new ArrayList<>();
		Class<?>[] rbf = attributes.getClassArray("rollbackFor");
		for (Class<?> rbRule : rbf) {
			RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		String[] rbfc = attributes.getStringArray("rollbackForClassName");
		for (String rbRule : rbfc) {
			RollbackRuleAttribute rule = new RollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		Class<?>[] nrbf = attributes.getClassArray("noRollbackFor");
		for (Class<?> rbRule : nrbf) {
			NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		String[] nrbfc = attributes.getStringArray("noRollbackForClassName");
		for (String rbRule : nrbfc) {
			NoRollbackRuleAttribute rule = new NoRollbackRuleAttribute(rbRule);
			rollBackRules.add(rule);
		}
		rbta.getRollbackRules().addAll(rollBackRules);
		return rbta;
	}

拦截:
TransactionInterceptor
保存了事务属性信息,事务管理器。
继承了MethodInterceptor接口,方式和 AOP 差不多。
TransactionInterceptor
既然是个拦截器,那么方法执行流程就和这个类有关,见《声明式事务原理——2. 方法调用流程 》。


相关文章:
AOP原理——1. @EnableAspectJAutoProxy
AOP原理——2. AbstractAutoProxyCreator 创建动态代理对象
声明式事务原理——2. 方法调用流程

posted @ 2020-12-05 13:01  qianbuhan  阅读(713)  评论(0)    收藏  举报