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

目录
相关文章
|
1月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
77 2
|
1月前
|
数据采集 监控 前端开发
二级公立医院绩效考核系统源码,B/S架构,前后端分别基于Spring Boot和Avue框架
医院绩效管理系统通过与HIS系统的无缝对接,实现数据网络化采集、评价结果透明化管理及奖金分配自动化生成。系统涵盖科室和个人绩效考核、医疗质量考核、数据采集、绩效工资核算、收支核算、工作量统计、单项奖惩等功能,提升绩效评估的全面性、准确性和公正性。技术栈采用B/S架构,前后端分别基于Spring Boot和Avue框架。
|
24天前
|
缓存 安全 Java
Spring高手之路26——全方位掌握事务监听器
本文深入探讨了Spring事务监听器的设计与实现,包括通过TransactionSynchronization接口和@TransactionalEventListener注解实现事务监听器的方法,并通过实例详细展示了如何在事务生命周期的不同阶段执行自定义逻辑,提供了实际应用场景中的最佳实践。
42 2
Spring高手之路26——全方位掌握事务监听器
|
23天前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
44 2
|
26天前
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
|
1月前
|
Java 开发者 Spring
Spring高手之路24——事务类型及传播行为实战指南
本篇文章深入探讨了Spring中的事务管理,特别是事务传播行为(如REQUIRES_NEW和NESTED)的应用与区别。通过详实的示例和优化的时序图,全面解析如何在实际项目中使用这些高级事务控制技巧,以提升开发者的Spring事务管理能力。
56 1
Spring高手之路24——事务类型及传播行为实战指南
|
1月前
|
JavaScript Java 关系型数据库
Spring事务失效的8种场景
本文总结了使用 @Transactional 注解时事务可能失效的几种情况,包括数据库引擎不支持事务、类未被 Spring 管理、方法非 public、自身调用、未配置事务管理器、设置为不支持事务、异常未抛出及异常类型不匹配等。针对这些情况,文章提供了相应的解决建议,帮助开发者排查和解决事务不生效的问题。
|
1月前
|
前端开发 Java 开发者
Spring生态学习路径与源码深度探讨
【11月更文挑战第13天】Spring框架作为Java企业级开发中的核心框架,其丰富的生态系统和强大的功能吸引了无数开发者的关注。学习Spring生态不仅仅是掌握Spring Framework本身,更需要深入理解其周边组件和工具,以及源码的底层实现逻辑。本文将从Spring生态的学习路径入手,详细探讨如何系统地学习Spring,并深入解析各个重点的底层实现逻辑。
67 9
|
1月前
|
XML Java 数据库连接
Spring中的事务是如何实现的
Spring中的事务管理机制通过一系列强大的功能和灵活的配置选项,为开发者提供了高效且可靠的事务处理手段。无论是通过注解还是AOP配置,Spring都能轻松实现复杂的事务管理需求。掌握这些工具和最佳实践,能
58 3
|
2月前
|
Java Spring
Spring底层架构源码解析(三)
Spring底层架构源码解析(三)
169 5