Spring源码 (事务篇) - 整体流程

在这里插入图片描述
在这里插入图片描述

1、解析配置文件

1.1 、解析配置文件的阶段

处理配置文件是在 refresh => invokeBeanFactoryPostProcessors ,即在调用 BeanFactory后置处理器阶段 对配置文件进行解析。
其中有个ConfigurationClassPostProcessor 类,该类是BeanDefinitionRegistryPostProcessor接口类型,该接口定义了注册BeanDefinition的规范。
postProcessBeanDefinitionRegistry方法中创建ConfigurationClassParser对象,调用其parse方法来解析配置文件并注册相关的BeanDefinition。

⭐️ 关键点⭐️
refresh => invokeBeanFactoryPostProcessors
BeanDefinitionRegistryPostProcessor#postProcessBeanDefinitionRegistry
ConfigurationClassPostProcessor #postProcessBeanDefinitionRegistry
ConfigurationClassParser#.parse

1.2、解析配置文件的方式

具体的解析在解析过程是循环递归的,即会解析配置文件的注解,解析注解的注解…, 层层递归。

1.3、案例解析

首先看看递归解析注解的调用栈:

collectImports:525, ConfigurationClassParser (org.springframework.context.annotation) [2]
collectImports:520, ConfigurationClassParser (org.springframework.context.annotation) [1]
getImports:496, ConfigurationClassParser (org.springframework.context.annotation)
----------------------------------------------------------------------------------------------------
doProcessConfigurationClass:287, ConfigurationClassParser (org.springframework.context.annotation)
processConfigurationClass:226, ConfigurationClassParser (org.springframework.context.annotation)
parse:181, ConfigurationClassParser (org.springframework.context.annotation)
parse:149, ConfigurationClassParser (org.springframework.context.annotation)
processConfigBeanDefinitions:304, ConfigurationClassPostProcessor (org.springframework.context.annotation)
postProcessBeanDefinitionRegistry:220, ConfigurationClassPostProcessor (org.springframework.context.annotation)
invokeBeanDefinitionRegistryPostProcessors:290, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:89, PostProcessorRegistrationDelegate (org.springframework.context.support)
invokeBeanFactoryPostProcessors:703, AbstractApplicationContext (org.springframework.context.support)
refresh:520, AbstractApplicationContext (org.springframework.context.support)
main:17, TXSpringTest (com.yh.stu.spring.annotation.tx)

(1)找到配置类TXConf(processConfigBeanDefinitions:304)
(2)解析配置类(parse:149),
(3)循环递归找到@EnableTransactionManagement注解的注解@Import(TransactionManagementConfigurationSelector.class)
(4)


while TXConf 的配置{//1-processConfigurationClass
 //2-doProcessConfigurationClass
 @Component
 
 @ropertySource
 
 @ComponentScan{
	//1-processConfigurationClass
	while OrderDao 的配置{
	 @Component
	 @ropertySource
	 @ComponentScan{}
	 for 递归 @Import 注解{
	 
	 }
	}
 }
 
 @Import{
	for递归收集注解中@Import导入的类,放入set中{
		......
	}
	例: (TXConf.java)事务配置TXConf的注解@EnableTransactionManagement的注解@Import(TransactionManagementConfigurationSelector.class)
	
	processImports方法for循环处理set中的3种类{
		1、ImportSelector类型的类 
		事务示例:TransactionManagementConfigurationSelector,实例化该类,然后调用它的接口方法selectImports,返回2个类名称的数组:
		return new String[] {AutoProxyRegistrar.class.getName(),
						ProxyTransactionManagementConfiguration.class.getName()};
		
		递归调用processImports方法,处理AutoProxyRegistrar、ProxyTransactionManagementConfiguration
		
		2、ImportBeanDefinitionRegistrar类型的类
		事务示例:AutoProxyRegistrar是这个类型的类,创建类对象,将其放入配置类TXConf包装类ConfigurationClass的Map属性中
		
		3、非以上两种类型
		事务示例:ProxyTransactionManagementConfiguration就是该类型,此时把该类当做类似TXConf的普通的配置类,以上所有的处理流程都要针对其进行处理。所以说整个配置文件的解析过程是个 “递归解析的过程” 
	}
 }
 
 @ImportResource
 @Bean
}

⭐️总结一下
1、Spring中类似TXConf的配置文件是可以有多个的,while解析多个配置文件
2、处理@Import注解导入的类过程存在递归调用,分别是1、3两种类型,1递归processImports方法 、3递归processConfigurationClass方法

2、解析 ProxyTransactionManagementConfiguration ,得到4个类

上一节分析了配置文件的解析过程,我们这里把 ProxyTransactionManagementConfiguration 配置文件的解析过程独立出来分析,因为本类主要是和事务相关的内容。

我们看ProxyTransactionManagementConfiguration 的源码,都是通过@Bean标注的方法进行Bean的注册

@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() {
		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;
	}
}
public abstract class AbstractTransactionManagementConfiguration implements ImportAware {
	@Bean(name = TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public static TransactionalEventListenerFactory transactionalEventListenerFactory() {
		return new TransactionalEventListenerFactory();
	}
}

⭐️ 解析出了4个类
1、BeanFactoryTransactionAttributeSourceAdvisor
2、AnnotationTransactionAttributeSource
3、TransactionInterceptor
4、TransactionalEventListenerFactory (父类)

3、注册BeanDefinition

解析完配置后,一切准备就绪,每个配置文件都会被封装为ConfigurationClass,此时new 一个ConfigurationClassBeanDefinitionReader对象,调用 loadBeanDefinitions(configClasses)。

一般情况下ConfigurationClass对象有多个,包括用户@Configuration配置的,还有配置文件中@ComponentScan扫描的,@Import注解中 “导入”的带@Configuration注解的。

loadBeanDefinitions for循环遍历多个ConfigurationClass
org.springframework.context.annotation.ConfigurationClassBeanDefinitionReader#loadBeanDefinitionsForConfigurationClass

private void loadBeanDefinitionsForConfigurationClass(
			ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

		if (trackedConditionEvaluator.shouldSkip(configClass)) {
			String beanName = configClass.getBeanName();
			if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
				this.registry.removeBeanDefinition(beanName);
			}
			this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
			return;
		}

		if (configClass.isImported()) {
			registerBeanDefinitionForImportedConfigurationClass(configClass);
			SS.l("注册"+SS.sn(configClass.getBeanName())+" 配置类本身的 BeanDefinition.");
		}
		for (BeanMethod beanMethod : configClass.getBeanMethods()) {
			loadBeanDefinitionsForBeanMethod(beanMethod);
		}

		loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
		loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
	}

上文提到了
【事务示例:
AutoProxyRegistrar是ImportBeanDefinitionRegistrar类型的类,创建类的对象,将其放入配置类TXConf包装类ConfigurationClass的Map属性中】
在最后一步,loadBeanDefinitionsFromRegistrars方法中会处理,AutoProxyRegistrar 的registerBeanDefinitions 方法中会注册InfrastructureAdvisorAutoProxyCreator,该类BeanPostProcessor接口的实现类。

3、创建Bean - BeanFactoryTransactionAttributeSourceAdvisor
创建TXConf实例时(doCreateBean(..))initializeBean(..)方法对其进行初始化, for 循环遍历所有的BeanPostProcessor{
	调用InfrastructureAdvisorAutoProxyCreator.postProcessAfterInitialization(..){
		wrapIfNecessary(..){// 对TXConf实例尝试创建代理对象
			从BeanFactory中找出所有的Advisor,发现BeanFactoryTransactionAttributeSourceAdvisor的 Bean 还没有创建该
			创建 BeanFactoryTransactionAttributeSourceAdvisor 的Bean{
				调用 ProxyTransactionManagementConfiguration#transactionAdvisor创建BeanFactoryTransaction???Advisor
				// 注意:BeanFactoryTransactionAttributeSourceAdvisor 是通过 @Bean 方法创建的,transactionAdvisor方法中还调用了
				// 其他两个方法				
			}
		}
	}
}

方法 ProxyTransactionManagementConfiguration#transactionAdvisor 如下:

	@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;
	}
4、用 InfrastructureAdvisorAutoProxyCreator 创建代理对象

在创建OrderSerivceImpl对象后,对象进行初始化(AbstractAutowireCapableBeanFactory#initializeBean)。
调用 InfrastructureAdvisorAutoProxyCreator(BeanPostProcessor类型 )的 applyBeanPostProcessorsAfterInitialization 方法,方法中调用对需要代理的对象进行创建代理对象(AbstractAutoProxyCreator#wrapIfNecessary)

wrapIfNecessary:342, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
postProcessAfterInitialization:293, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsAfterInitialization:385, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1740, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:551, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:471, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
lambda$doGetBean$0:277, AbstractBeanFactory (org.springframework.beans.factory.support)
getObject:-1, 854507466 (org.springframework.beans.factory.support.AbstractBeanFactory$$Lambda$12)
getSingleton:211, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:275, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:155, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:802, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:876, AbstractApplicationContext (org.springframework.context.support)
refresh:544, AbstractApplicationContext (org.springframework.context.support)
main:17, TXSpringTest (com.yh.stu.spring.annotation.tx)
4.1、获取Bean的Advisor

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean

protected Object[] getAdvicesAndAdvisorsForBean(
			Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

		List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
		if (advisors.isEmpty()) {
			return DO_NOT_PROXY;
		}
		return advisors.toArray();
	}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

findCandidateAdvisors()方法会找出所有的 Advisor 对象,包括 BeanFactoryTransactionAttributeSourceAdvisor 类的对象
findAdvisorsThatCanApply方法找出Bean适用的Advisor对象,比如 BeanFactoryTransactionAttributeSourceAdvisor 类的对象

4.2、createProxy 创建代理对象

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
			@Nullable Object[] specificInterceptors, TargetSource targetSource) {

		if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
			AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory)this.beanFactory, beanName, beanClass);
		}

		ProxyFactory proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

		if (!proxyFactory.isProxyTargetClass()) {
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}
		//确定给定bean的advisor,包括特定的拦截器和通用的拦截器,所有这些都是Advisor接口的实现类。
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		return proxyFactory.getProxy(getProxyClassLoader());
	}

ProxyFactory#getProxy方法返回 DefaultAopProxyFactory 类型的对象

    public Object getProxy(@Nullable ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }

DefaultAopProxyFactory#createAopProxy 方法 返回 JdkDynamicAopProxy 或 ObjenesisCglibAopProxy,参考

    @Override
	public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
			Class<?> targetClass = config.getTargetClass();
			if (targetClass == null) {
				throw new AopConfigException("TargetSource cannot determine target class: " +
						"Either an interface or a target is required for proxy creation.");
			}
			if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}
5、调用加了@Transaction 注解的方法

TransactionAspectSupport#invokeWithinTransaction

invokeWithinTransaction:286, TransactionAspectSupport (org.springframework.transaction.interceptor)
invoke:98, TransactionInterceptor (org.springframework.transaction.interceptor)
proceed:186, ReflectiveMethodInvocation (org.springframework.aop.framework)
invoke:209, JdkDynamicAopProxy (org.springframework.aop.framework)
queryAll:-1, $Proxy22 (com.sun.proxy)
main:18, TXSpringTest (com.yh.stu.spring.annotation.tx)

说说事务未生效的几种情况?

为什么我的事务不生效
1.如果不是Innodb存储引擎,MyISAM不支持事务。
2.没有指定rollbackFor参数。
3. 没有指定transactionManager参数,默认的transactionManager并不是我期望的,以及一个事务中涉及到了多个数据库。
4. 如果AOP使用了JDK动态代理,对象内部方法互相调用不会被Spring的AOP拦截,@Transactional注解无效。
5. 如果AOP使用了CGLIB代理,事务方法或者类不是public,无法被外部包访问到,或者是final无法继承,@transactional注解无效。

https://www.cnblogs.com/dennyzhangdd/p/9602673.html

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

java硕哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值