Spring事务(源码详解)

简介: Spring事务(源码详解)

之前说到了“编程式事务管理”以及“声明式事务管理”,

下面我们来分析一下这两个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

目录
相关文章
|
26天前
|
缓存 Java 开发工具
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
三级缓存是Spring框架里,一个经典的技术点,它很好地解决了循环依赖的问题,也是很多面试中会被问到的问题,本文从源码入手,详细剖析Spring三级缓存的来龙去脉。
Spring是如何解决循环依赖的?从底层源码入手,详细解读Spring框架的三级缓存
|
14天前
|
Java 数据库连接 数据库
spring复习05,spring整合mybatis,声明式事务
这篇文章详细介绍了如何在Spring框架中整合MyBatis以及如何配置声明式事务。主要内容包括:在Maven项目中添加依赖、创建实体类和Mapper接口、配置MyBatis核心配置文件和映射文件、配置数据源、创建sqlSessionFactory和sqlSessionTemplate、实现Mapper接口、配置声明式事务以及测试使用。此外,还解释了声明式事务的传播行为、隔离级别、只读提示和事务超时期间等概念。
spring复习05,spring整合mybatis,声明式事务
|
16天前
|
Java 测试技术 数据库
Spring事务传播机制(最全示例)
在使用Spring框架进行开发时,`service`层的方法通常带有事务。本文详细探讨了Spring事务在多个方法间的传播机制,主要包括7种传播类型:`REQUIRED`、`SUPPORTS`、`MANDATORY`、`REQUIRES_NEW`、`NOT_SUPPORTED`、`NEVER` 和 `NESTED`。通过示例代码和数据库插入测试,逐一展示了每种类型的运作方式。例如,`REQUIRED`表示如果当前存在事务则加入该事务,否则创建新事务;`SUPPORTS`表示如果当前存在事务则加入,否则以非事务方式执行;`MANDATORY`表示必须在现有事务中运行,否则抛出异常;
57 4
Spring事务传播机制(最全示例)
|
4天前
|
Java Spring 容器
Spring IOC、AOP与事务管理底层原理及源码解析
Spring框架以其强大的控制反转(IOC)和面向切面编程(AOP)功能,成为Java企业级开发中的首选框架。本文将深入探讨Spring IOC和AOP的底层原理,并通过源码解析来揭示其实现机制。同时,我们还将探讨Spring事务管理的核心原理,并给出相应的源码示例。
35 9
|
2天前
|
存储 开发框架 Java
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
文章详细介绍了Spring、IOC、DI的概念和关系,解释了控制反转(IOC)和依赖注入(DI)的原理,并提供了IOC的代码示例,阐述了Spring框架作为IOC容器的应用。
4 0
什么是Spring?什么是IOC?什么是DI?IOC和DI的关系? —— 零基础可无压力学习,带源码
|
11天前
|
缓存 Java Spring
手写Spring Ioc 循环依赖底层源码剖析
在Spring框架中,IoC(控制反转)是一个核心特性,它通过依赖注入(DI)实现了对象间的解耦。然而,在实际开发中,循环依赖是一个常见的问题。
23 4
|
12天前
|
Java Spring
Spring 事务传播机制是什么?
Spring 事务传播机制是什么?
17 4
|
16天前
|
XML 缓存 Java
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
spring源码剖析-spring-beans(内部核心组件,BeanDefinition的注册,BeanWapper创建)
43 10
|
16天前
|
XML 存储 Java
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
spring源码刨析-spring-beans(内部核心组件,beanDefinition加载过程)
|
16天前
|
XML 存储 Java
Spring-源码深入分析(二)
Spring-源码深入分析(二)