之前说到了“编程式事务管理”以及“声明式事务管理”,
下面我们来分析一下这两个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) :当容器中只存在一个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继承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