之前说到了“编程式事务管理”以及“声明式事务管理”,下面我们来分析一下这两个Spring实现原理以及看下源代码
编程式事务管理
编程式事务管理调用了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
实现了TransactionDefinition
和Serializable
其主要做的事情是: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.class
,HibernateJpaAutoConfiguration.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) : 当容器中只存在一个
PlatformTransactionManager
Bean的时候,该配置类才进行解析
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
继承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。
其中获取了AutoProxyRegistrar
和 ProxyTransactionManagementConfiguration
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();
}
- 当获得该bean时,会将beanFactory中所有TransactionManagementConfigurer类型得到bean传递给该函数
- 如果configurers为空,直接return
- 如果有多个TransactionManagementConfigurer类型的bean,则抛出IllegalStateException
- 获得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
.
由于EnableConfigurationPropertiesImportSelector
是 ImportSelector
的实现,调用其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
方法,进行注册.
由于在JdkDynamicAutoProxyConfiguration
中importBeanDefinitionRegistrars
配置有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
- 注册id为