Spring事务(五、源码详解)

之前说到了“编程式事务管理”以及“声明式事务管理”,下面我们来分析一下这两个Spring实现原理以及看下源代码

编程式事务管理

编程式事务管理调用了TransactionTemplate。那就从这里入手
看下TransactionTemplate的继承结构:
TransactionTemplate
可以看到继承了DefaultTransactionDefinition类,同时实现了TransactionOperations 以及 InitializingBean
先看实现父类:

InitializingBean

public interface InitializingBean {

	/**
	 * Invoked by a BeanFactory after it has set all bean properties supplied
	 * (and satisfied BeanFactoryAware and ApplicationContextAware).
	 * <p>This method allows the bean instance to perform initialization only
	 * possible when all bean properties have been set and to throw an
	 * exception in the event of misconfiguration.
	 * @throws Exception in the event of misconfiguration (such
	 * as failure to set an essential property) or if initialization fails.
	 */
	void afterPropertiesSet() throws Exception;

}

InitializingBean只定义了一个回调方法,在BeanFactory加载完Bean之后,进行回调

看下实现:

TransactionTemplate.afterPropertiesSet

	@Override
	public void afterPropertiesSet() {
		if (this.transactionManager == null) {
			throw new IllegalArgumentException("Property 'transactionManager' is required");
		}
	}

很简单,只是判断了事务管理器不为空。为空的话,抛出异常。

TransactionOperations

public interface TransactionOperations {

	/**
	 * Execute the action specified by the given callback object within a transaction.
	 * <p>Allows for returning a result object created within the transaction, that is,
	 * a domain object or a collection of domain objects. A RuntimeException thrown
	 * by the callback is treated as a fatal exception that enforces a rollback.
	 * Such an exception gets propagated to the caller of the template.
	 * @param action the callback object that specifies the transactional action
	 * @return a result object returned by the callback, or {@code null} if none
	 * @throws TransactionException in case of initialization, rollback, or system errors
	 * @throws RuntimeException if thrown by the TransactionCallback
	 */
	@Nullable
	<T> T execute(TransactionCallback<T> action) throws TransactionException;

}

TransactionOperations只有一个execute方法,看下TransactionTemplate是怎么实现的:

TransactionTemplate.execute

	@Override
	@Nullable
	public <T> T execute(TransactionCallback<T> action) throws TransactionException {
		// 判断事务管理器是否为null
		Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");

		// 判断事务管理器是否是CallbackPreferringPlatformTransactionManager的一个实例。
		// 如果是,返回CallbackPreferringPlatformTransactionManager的excute方法。
		if (this.transactionManager instanceof CallbackPreferringPlatformTransactionManager) {
			return ((CallbackPreferringPlatformTransactionManager) this.transactionManager).execute(this, action);
		}
		else {
			// 获取事务状态
			TransactionStatus status = this.transactionManager.getTransaction(this);
			T result;
			// 执行业务逻辑,获取结果
			try {
				result = action.doInTransaction(status);
			}
			// 捕获运行时异常异常
			catch (RuntimeException | Error ex) {
				// 回滚并抛出异常
				// Transactional code threw application exception -> rollback
				rollbackOnException(status, ex);
				throw ex;
			}
			catch (Throwable ex) {
				// // 回滚并抛出异常
				// Transactional code threw unexpected exception -> rollback
				rollbackOnException(status, ex);
				throw new UndeclaredThrowableException(ex, "TransactionCallback threw undeclared checked exception");
			}
			// 事务提交
			this.transactionManager.commit(status);
			return result;
		}
	}

TransactionTemplate继承了DefaultTransactionDefinition类,但是通过看源码并没有重写其中的方法。所以我们简单看下DefaultTransactionDefinition类的方法图,看看做了什么:
DefaultTransactionDefinition
可见DefaultTransactionDefinition实现了TransactionDefinitionSerializable
其主要做的事情是:set/get事务等级,set/get隔离级别,set/get超时时间。。。???好像有点熟悉啊,这不是@Transaction的属性吗。接下来看下声明式事务管理

声明式事务管理

既然使用注解形式,那少不了自动配置。在spring.factories中找到了两个关于事务的自动配置类:

org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\

JtaAutoConfiguration

/**
 * {@link EnableAutoConfiguration Auto-configuration} for JTA.
 *
 * @author Josh Long
 * @author Phillip Webb
 * @since 1.2.0
 */
@ConditionalOnClass(javax.transaction.Transaction.class)
@ConditionalOnProperty(prefix = "spring.jta", value = "enabled", matchIfMissing = true)
@AutoConfigureBefore({ XADataSourceAutoConfiguration.class,
		ActiveMQAutoConfiguration.class, ArtemisAutoConfiguration.class,
		HibernateJpaAutoConfiguration.class })
@Import({ JndiJtaConfiguration.class, BitronixJtaConfiguration.class,
		AtomikosJtaConfiguration.class, NarayanaJtaConfiguration.class })
@EnableConfigurationProperties(JtaProperties.class)
public class JtaAutoConfiguration {

}

JtaAutoConfiguration并没有内部逻辑,只是一个标识性的类,重点在其注解上:

  • 当前类路径下存在javax.transaction.Transaction时该配置生效。
  • 判断配置文件中是否存在某个配置 spring.jta.enabled = true的时候才生效。
  • 在指定的配置类初始化前加载 :XADataSourceAutoConfiguration.class, ActiveMQAutoConfiguration.class, ArtemisAutoConfiguration.class,HibernateJpaAutoConfiguration.class
  • 注入类:JndiJtaConfiguration.class, BitronixJtaConfiguration.class, AtomikosJtaConfiguration.class, NarayanaJtaConfiguration.class
  • 使 使用 @ConfigurationProperties 注解的类 - JtaProperties.class生效。

TransactionAutoConfiguration

/**
 * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration
 * Auto-configuration} for Spring transaction.
 *
 * @author Stephane Nicoll
 * @since 1.3.0
 */
@Configuration
@ConditionalOnClass(PlatformTransactionManager.class)
@AutoConfigureAfter({ JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class,
		DataSourceTransactionManagerAutoConfiguration.class,
		Neo4jDataAutoConfiguration.class })
@EnableConfigurationProperties(TransactionProperties.class)
public class TransactionAutoConfiguration {

	@Bean
	@ConditionalOnMissingBean
	public TransactionManagerCustomizers platformTransactionManagerCustomizers(
			ObjectProvider<List<PlatformTransactionManagerCustomizer<?>>> customizers) {
		return new TransactionManagerCustomizers(customizers.getIfAvailable());
	}

	@Configuration
	@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
	public static class TransactionTemplateConfiguration {

		private final PlatformTransactionManager transactionManager;

		public TransactionTemplateConfiguration(
				PlatformTransactionManager transactionManager) {
			this.transactionManager = transactionManager;
		}

		@Bean
		@ConditionalOnMissingBean
		public TransactionTemplate transactionTemplate() {
			return new TransactionTemplate(this.transactionManager);
		}
	}

	@Configuration
	@ConditionalOnBean(PlatformTransactionManager.class)
	@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
	public static class EnableTransactionManagementConfiguration {

		@Configuration
		@EnableTransactionManagement(proxyTargetClass = false)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
		public static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration
		@EnableTransactionManagement(proxyTargetClass = true)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
		public static class CglibAutoProxyConfiguration {

		}

	}

}

TransactionAutoConfiguration 注解

  • @Configuration :标志其为一个配置类
  • @ConditionalOnClass(PlatformTransactionManager.class) : 当前类路径下存在PlatformTransactionManager.class 时该配置生效
  • @AutoConfigureAfter:在JtaAutoConfiguration.classHibernateJpaAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class,Neo4jDataAutoConfiguration.class 之后才解析该类.
  • @EnableConfigurationProperties(TransactionProperties.class) : 使 使用 @ConfigurationProperties 注解的类 - TransactionProperties.class生效。

public方法 - platformTransactionManagerCustomizers

判断如果没有TransactionManagerCustomizers对象,则返回一个新的TransactionManagerCustomizers对象

	@Bean
	@ConditionalOnMissingBean
	public TransactionManagerCustomizers platformTransactionManagerCustomizers(
			ObjectProvider<List<PlatformTransactionManagerCustomizer<?>>> customizers) {
		return new TransactionManagerCustomizers(customizers.getIfAvailable());
	}

内部类

TransactionTemplateConfiguration
	@Configuration
	@ConditionalOnSingleCandidate(PlatformTransactionManager.class)
	public static class TransactionTemplateConfiguration {

		private final PlatformTransactionManager transactionManager;

		public TransactionTemplateConfiguration(
				PlatformTransactionManager transactionManager) {
			this.transactionManager = transactionManager;
		}

		@Bean
		@ConditionalOnMissingBean
		public TransactionTemplate transactionTemplate() {
			return new TransactionTemplate(this.transactionManager);
		}
	}
TransactionTemplateConfiguration 注解
  • @Configuration : 配置类
  • @ConditionalOnSingleCandidate(PlatformTransactionManager.class) : 当容器中只存在一个PlatformTransactionManagerBean的时候,该配置类才进行解析
EnableTransactionManagementConfiguration
	@Configuration
	@ConditionalOnBean(PlatformTransactionManager.class)
	@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)
	public static class EnableTransactionManagementConfiguration {

		@Configuration
		@EnableTransactionManagement(proxyTargetClass = false)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
		public static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration
		@EnableTransactionManagement(proxyTargetClass = true)
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
		public static class CglibAutoProxyConfiguration {

		}

	}
EnableTransactionManagementConfiguration注解
  • @Configuration :配置类
  • @ConditionalOnBean(PlatformTransactionManager.class) :当beanFactory中存在PlatformTransactionManager类型的bean时该配置生效
  • @ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)–> 当不存在AbstractTransactionManagementConfiguration的bean时生效.
EnableTransactionManagementConfiguration 内部类

		@Configuration
		// 启用TransactionManagement, proxyTargetClass = false,表示是面向接口代理。
		@EnableTransactionManagement(proxyTargetClass = false)
		// 配置有spring.aop.proxy-target-class = false时生效,如果没配置,则不生效
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
		public static class JdkDynamicAutoProxyConfiguration {

		}

		@Configuration
		// 启用TransactionManagement, proxyTargetClass = false,表示是面向接口代理。
		@EnableTransactionManagement(proxyTargetClass = true)
		// 配置有spring.aop.proxy-target-class = true时生效,如果没配置,则不生效
		@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
		public static class CglibAutoProxyConfiguration {

		}

可以看到EnableTransactionManagementConfiguration 其实是使用两种代理方式,Jdk代理以及Cglib代理(想到代理模式又想到AOP了),其中最重要的注解是@EnableTransactionManagement。同时EnableTransactionManagementConfiguration默认的代理方式是Jdk代理。我们看下注解:@EnableTransactionManagement

@EnableTransactionManagement
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

	/**
	 * 为false的时候,执行的是JDK代理。默认值
	 * 为true 的时候,执行的是Cglib代理。
	 */
	boolean proxyTargetClass() default false;

	/**
	 * 表明transactional 切面是如何织入的,默认是代理
	 */
	AdviceMode mode() default AdviceMode.PROXY;

	/**
	 * aop的优先级
	 */
	int order() default Ordered.LOWEST_PRECEDENCE;

}

通过@Import(TransactionManagementConfigurationSelector.class)TransactionManagementConfigurationSelector导入

TransactionManagementConfigurationSelector
TransactionManagementConfigurationSelector体系结构
TransactionManagementConfigurationSelector
由此我们可知TransactionManagementConfigurationSelector继承AdviceModeImportSelector,而AdviceModeImportSelector继承Annotation 并 实现了 ImportSelector
其中重写方法:

	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
		switch (adviceMode) {
			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;
		}
	}

因为之前讲到默认是:PROXY,所以走第一个case。

其中获取了AutoProxyRegistrarProxyTransactionManagementConfiguration

ProxyTransactionManagementConfiguration

@Configuration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {

	// 声明的第一个Bean:org.springframework.transaction.config.internalTransactionAdvisor
	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
		// 实例化BeanFactoryTransactionAttributeSourceAdvisor
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		// 配置 transactionAttributeSource
		advisor.setTransactionAttributeSource(transactionAttributeSource());
		// 配置 Advice–>切面
		advisor.setAdvice(transactionInterceptor());
		if (this.enableTx != null) {
			// 配置aop优先级–>默认Integer.MAX_VALUE
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

	// 声明的第二个Bean : transactionAttributeSource,为内部使用Bean
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
		return new AnnotationTransactionAttributeSource();
	}


	// 声明的第三个Bean : transactionInterceptor
	@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;
	}

}

可见ProxyTransactionManagementConfiguration 继承 AbstractTransactionManagementConfiguration,而 AbstractTransactionManagementConfiguration 实现了 ImportAware

所以AbstractTransactionManagementConfiguration实现了ImportAware接口.因此会调用其setImportMetadata方法.代码如下:

	@Override
	public void setImportMetadata(AnnotationMetadata importMetadata) {
		this.enableTx = AnnotationAttributes.fromMap(
				importMetadata.getAnnotationAttributes(EnableTransactionManagement.class.getName(), false));
		if (this.enableTx == null) {
			throw new IllegalArgumentException(
					"@EnableTransactionManagement is not present on importing class " + importMetadata.getClassName());
		}
	}

从@EnableTransactionManagement 中获取配置信息,封装为AnnotationAttributes.如果@EnableTransactionManagement没有配置属性的话,就会返回null,此时就会抛出IllegalArgumentException.

同时在AbstractTransactionManagementConfiguration声明了一个被@Autowired(required = false)注解的方法:

	@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();
	}
  1. 当获得该bean时,会将beanFactory中所有TransactionManagementConfigurer类型得到bean传递给该函数
  2. 如果configurers为空,直接return
  3. 如果有多个TransactionManagementConfigurer类型的bean,则抛出IllegalStateException
  4. 获得PlatformTransactionManager

注意: TransactionManagementConfigurer在spring 中没有实现,因此正常情况下是不会有TransactionManagementConfigurer类型的bean

同时在AbstractTransactionManagementConfiguration中注册了一个id为org.springframework.transaction.config.internalTransactionalEventListenerFactory,类型为TransactionalEventListenerFactory,角色为内部使用的bean,代码如下:

	@Bean(name = TransactionManagementConfigUtils.TRANSACTIONAL_EVENT_LISTENER_FACTORY_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionalEventListenerFactory transactionalEventListenerFactory() {
		return new TransactionalEventListenerFactory();
	}

AutoProxyRegistrar源码

public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	private final Log logger = LogFactory.getLog(getClass());
	
	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
		Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
		for (String annoType : annoTypes) {
			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
			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;
					}
				}
			}
		}
		if (!candidateFound) {
			String name = getClass().getSimpleName();
			logger.warn(String.format("%s was imported but no annotations were found " +
					"having both 'mode' and 'proxyTargetClass' attributes of type " +
					"AdviceMode and boolean respectively. This means that auto proxy " +
					"creator registration and configuration may not have occurred as " +
					"intended, and components may not be proxied as expected. Check to " +
					"ensure that %s has been @Import'ed on the same class where these " +
					"annotations are declared; otherwise remove the import of %s " +
					"altogether.", name, name, name));
		}
	}

}

AutoProxyRegistrar 实现 ImportBeanDefinitionRegistrar ,并重写了其registerBeanDefinitions方法,因此会将其实例化后,加入到JdkDynamicAutoProxyConfiguration所对应的ConfigurationClass中的importBeanDefinitionRegistrars

其中可以找到代码if (mode == AdviceMode.PROXY) 此处判断为代理模式。而if ((Boolean) proxyTargetClass) 判断是CGLOB子类代理模式。

AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry); 一步一步往下走,可以找到,最终调用的是org.springframework.aop.config.AopConfigUtils

	/**
	 * Setup the escalation list.
	 */
	static {
		APC_PRIORITY_LIST.add(InfrastructureAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AspectJAwareAdvisorAutoProxyCreator.class);
		APC_PRIORITY_LIST.add(AnnotationAwareAspectJAutoProxyCreator.class);
	}
	
	@Nullable
	private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry,
			@Nullable Object source) {

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		// 判断当前注解器是否包含 :AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
		if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
			BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
			// 如果当前类不是:"org.springframework.aop.config.internalAutoProxyCreator"
			if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
				int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
				int requiredPriority = findPriorityForClass(cls);
				// 如果下标大于已存在的内部自动代理构造器,index越小,优先级越高,InfrastructureAdvisorAutoProxyCreator index=0,requiredPriority最小,不进入
				if (currentPriority < requiredPriority) {
					apcDefinition.setBeanClassName(cls.getName());
				}
			}
			return null;
		}
		// 如果当前注册器不包含internalAutoProxyCreator,则把当前类作为根定义
		RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
		beanDefinition.setSource(source);
		// 优先级最高 (代码中静态代码块部分,优先级上升list)
		beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
		beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
		registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
		return beanDefinition;
	}

由于InfrastructureAdvisorAutoProxyCreator这个类在list中第一个index=0,requiredPriority最小,不进入,所以没有重置beanClassName,啥都没做,返回null.

ok,终于把内部类说完了。

由于TransactionAutoConfiguration声明了@EnableConfigurationProperties(TransactionProperties.class) 注解,而@EnableConfigurationProperties注解通过@Import(EnableConfigurationPropertiesImportSelector.class)引入了EnableConfigurationPropertiesImportSelector.

由于EnableConfigurationPropertiesImportSelectorImportSelector的实现,调用其selectImports方法返回的是ConfigurationPropertiesBeanRegistrar,ConfigurationPropertiesBindingPostProcessorRegistrar.

同时ConfigurationPropertiesBeanRegistrar, ConfigurationPropertiesBindingPostProcessorRegistrar都实现了ImportBeanDefinitionRegistrar,添加到TransactionAutoConfiguration对应的importBeanDefinitionRegistrars中.

接着,处理TransactionAutoConfiguration中被@bean注解的方法只有一个,代码如下:

	@Bean
	@ConditionalOnMissingBean	
	public TransactionManagerCustomizers platformTransactionManagerCustomizers(
			ObjectProvider<List<PlatformTransactionManagerCustomizer<?>>> customizers) {
		return new TransactionManagerCustomizers(customizers.getIfAvailable());
	}

TransactionAutoConfiguration 配置类解析完之后,会调用ConfigurationClassBeanDefinitionReader#loadBeanDefinitions。会依次处理TransactionAutoConfiguration配置类中生成的ConfigurationClass

ProxyTransactionManagementConfiguration 对应的ConfigurationClass,由于是被JdkDynamicAutoProxyConfiguration导入的,因此会调用ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass方法,代码如下:

	private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
		AnnotationMetadata metadata = configClass.getMetadata();
		AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);

		ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
		configBeanDef.setScope(scopeMetadata.getScopeName());
		String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
		AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);

		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
		configClass.setBeanName(configBeanName);

		if (logger.isDebugEnabled()) {
			logger.debug("Registered bean definition for imported class '" + configBeanName + "'");
		}
	}

BeanDefinitionRegistry进行注册.

同时,由于在ProxyTransactionManagementConfiguration中定义了4个@bean方法,因此会依次调用loadBeanDefinitionsForBeanMethod进行注册.

JdkDynamicAutoProxyConfiguration 是被EnableTransactionManagementConfiguration导入,因此同样会调用ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass方法,进行注册.

由于在JdkDynamicAutoProxyConfigurationimportBeanDefinitionRegistrars 配置有AutoProxyRegistrar,因此会调用AutoProxyRegistrar#registerBeanDefinitions.代码如下:

	@Override
	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		boolean candidateFound = false;
		Set<String> annoTypes = importingClassMetadata.getAnnotationTypes();
		for (String annoType : annoTypes) {
			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType);
			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;
					}
				}
			}
		}
		if (!candidateFound) {
			String name = getClass().getSimpleName();
			logger.warn(String.format("%s was imported but no annotations were found " +
					"having both 'mode' and 'proxyTargetClass' attributes of type " +
					"AdviceMode and boolean respectively. This means that auto proxy " +
					"creator registration and configuration may not have occurred as " +
					"intended, and components may not be proxied as expected. Check to " +
					"ensure that %s has been @Import'ed on the same class where these " +
					"annotations are declared; otherwise remove the import of %s " +
					"altogether.", name, name, name));
		}
	}

获得importingClassMetadata中的注解类型
依次遍历,如果遍历到@EnableTransactionManagement 注解

  • 如果@EnableTransactionManagement 配置的mode 为PROXY,则注册类型为InfrastructureAdvisorAutoProxyCreator,id为org.springframework.aop.config.internalAutoProxyCreator的bean
  • 如果@EnableTransactionManagement 配置的proxyTargetClass为true,则向beanFactory中id为org.springframework.aop.config.internalAutoProxyCreator的bean添加proxyTargetClass的属性,值为true
  • 如果最终没有找到@EnableTransactionManagement,则打印日志

EnableTransactionManagementConfiguration 是被TransactionAutoConfiguration 导入.因此会调用ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass方法进行注册

  • TransactionTemplateConfiguration 是被TransactionTemplateConfiguration导入的, 因此会调用ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass方法进行注册.同时由于声明了一个被@bean注解的方法,因此会调用loadBeanDefinitionsForBeanMethod进行注册
  • TransactionAutoConfiguration 是被启动类导入,因此会调用ConfigurationClassBeanDefinitionReader#registerBeanDefinitionForImportedConfigurationClass方法进行注册.

同时由于有一个被@bean注解的方法,因此会调用loadBeanDefinitionsForBeanMethod进行注册
最后,由于通过@EnableConfigurationProperties间接导入了2个BeanDefinitionsFromRegistrar。依次会依次调用其registerBeanDefinitions方法.

  • ConfigurationPropertiesBeanRegistrar : 会向BeanDefinitionRegistry注册一个id为spring.transaction-org.springframework.boot.autoconfigure.transaction.TransactionProperties,类型为TransactionProperties的bean

  • ConfigurationPropertiesBindingPostProcessorRegistrar: 如果BeanDefinitionRegistry中不存id为org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor的bean,则:

    • 注册id为org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor,类型为ConfigurationBeanFactoryMetaData的bean
    • 注册id为org.springframework.boot.context.properties.ConfigurationPropertiesBindingPostProcessor.store,类型为ConfigurationBeanFactoryMetaData的bean

参考大佬博文:spring boot 源码解析21-spring boot transaction自动化配置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值