Spring框架事务核心源码解析

详细分析了Spring事务管理的源码,包括7种传播特性在存在事务和不存在事务情况下的处理逻辑,顺带着也把AOP的核心源码也一起分析了。

@EnableTransactionManagement注解分析

事务代理对象的创建AOP代理对象的创建类似,要启动事务管理,需要在配置类上使用@EnableTransactionManagement注解,来看看这个注解做了些什么事情:

@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

    //代理对象是否使用CGLIB来创建
	boolean proxyTargetClass() default false;

    //默认使用代理模式
	AdviceMode mode() default AdviceMode.PROXY;

    //默认最低优先级(拦截链上最后执行)
	int order() default Ordered.LOWEST_PRECEDENCE;
}

看看 TransactionManagementConfigurationSelector 这个注册了些什么:

protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
		    //默认PROXY, 导入AutoProxyRegistrar 和 ProxyTransactionManagementConfiguration 。
			case PROXY:
				return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
			//ASPECTJ的方式会加载 AspectJTransactionManagementConfiguration
			case ASPECTJ:
				return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
			default:
				return null;
		}
	}

AutoProxyRegistrar 会往容器中注册 InfrastructureAdvisorAutoProxyCreator:

public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
		Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
		...
					//注册 InfrastructureAdvisorAutoProxyCreator 。
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
		...
		
	}

这儿注意一点的是,如果我们同时使用@EnableAspectJAutoProxy这个的话,上一篇文章解析过,它会注册 AnnotationAwareAspectJAutoProxyCreator 这个类型AutoProxyCreator,此时spring会选择一个来注册,具体为AopConfigUtils.registerOrEscalateApcAsRequired 方法:

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

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        
        //如果已经存在AutoProxyCreator,并且再次注册的class和已经注册的不一致,那么更具优先级进行替换(新注册的优先级高的话,就替换,否则不动)
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				if (currentPriority < requiredPriority) {
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}
    
        //注册具体的 AutoProxyCreator 。
		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;
	}

不通过类型的优先级定义:

static {
		APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
	}

简言之,如果@EnableAspectJAutoProxy启用的话,AutoProxyRegistrar其实没做啥子事情。

另外一个ProxyTransactionManagementConfiguration,是一个配置类,它主要会配置TransactionAttributeSource 、 TransactionInterceptor、 BeanFactoryTransactionAttributeSourceAdvisor:

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    
	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		//注入TransactionAttributeSource
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		//注入TransactionInterceptor
		advisor.setAdvice(transactionInterceptor());
		
		if (this.enableTx != null) {
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

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

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

}

事务代理对象的创建

@EnableTransactionManagement注解会注册 InfrastructureAdvisorAutoProxyCreator 或者使用 @EnableAspectJAutoProxy 的 AnnotationAwareAspectJAutoProxyCreator,无论使用哪一个,他们都继承至AbstractAutoProxyCreator(封装了核心逻辑),都是 InstantiationAwareBeanPostProcessor ,因此在getBean过程中,会触发 AbstractAutoProxyCreator.postProcessBeforeInstantiation 方法,这个方法在上一篇文章已经分析过了,对于我们事务来将,关键一步是

public List<Advisor> findAdvisorBeans() {

        //找到容器中所有的Advisor类型,并将名称缓存到cachedAdvisorBeanNames
        //这就会把前面配置中声明的BeanFactoryTransactionAttributeSourceAdvisor找到了。
		// Determine list of advisor bean names, if not cached already.
    		String[] advisorNames = this.cachedAdvisorBeanNames;
		if (advisorNames == null) {
			// Do not initialize FactoryBeans here: We need to leave all regular beans
			// uninitialized to let the auto-proxy creator apply to them!
			advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
					this.beanFactory, Advisor.class, true, false);
			this.cachedAdvisorBeanNames = advisorNames;
		}
		
		//没有找到返回空列表
		if (advisorNames.length == 0) {
			return new ArrayList<>();
		}
        
        //有的话,getBean,然后加入到列表中返回。
		List<Advisor> advisors = new ArrayList<>();
		for (String name : advisorNames) {
			if (isEligibleBean(name)) {
				...
				else {
					try {
						advisors.add(this.beanFactory.getBean(name, Advisor.class));
					}
					...
				}
			}
		}
		return advisors;
	}

同样,在AbstractAutoProxyCreator.postProcessAfterInitialization 方法中创建代理对象:

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (!this.earlyProxyReferences.contains(cacheKey)) {
		    //如果有必要的话,包装成代理对象
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

wrapIfNecessary的具体逻辑:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
		//一些前置校验
		....

        //找到适合当前bean的Advisor
		// Create proxy if we have advice.
		Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
		
		//如果有当前bean需要增强,则创建代理对象。
		if (specificInterceptors != DO_NOT_PROXY) {
			this.advisedBeans.put(cacheKey, Boolean.TRUE);
			
			//创建代理对象,具体的创建过程Aop源码分析中已经解析过了。
			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;
	}

代理对象的创建过程在前面AOP源码中已经分析过了,因此重点来看看针对事务的Advisor过程:

protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    //找到适合当前bean的advisor
	List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
	
	//如果为空,没找到,返回DO_NOT_PROXY(null,即不需要代理)
	if (advisors.isEmpty()) {
		return DO_NOT_PROXY;
	}
	return advisors.toArray();
}

findEligibleAdvisors方法:

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	//找到所有候选的Advisor。这一步前面已经分析过了,会找到容器中所有的Advisor,这里面就包括了事务的 BeanFactoryTransactionAttributeSourceAdvisor
	List<Advisor> candid
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值