Spring事务源码解析(一)@EnableTransactionManagement注解

测试Demo

本篇文章的Demo基于上一篇文章SpringJDBC源码解析@EnableTransactionManagementDataSourceTransactionManagerBean

@Beanpublic DataSourceTransactionManager 	
dataSourceTransactionManager(DruidDataSource druidDataSource) {    	
        return new DataSourceTransactionManager(druidDataSource);	
        }

在业务接口中新增一个抛出异常的修改方法

public interface JDBCService {	
    public void testTransactional();	
} 	
@Transactional	
public class JDBCServiceImpl implements JDBCService {	

	
    @Override	
    public void testTransactional() {	
        jdbcTemplate.update("update user set name='王五' where id=1", new Object[]{});	
        throw new RuntimeException("异常");	
    }	
}

启动Demo的类

public class TransactionalDemo {	
    public static void main (String args[]){	
        ApplicationContext context = new AnnotationConfigApplicationContext("cn.shiyujun.config");	
        JDBCService jdbcService=  context.getBean(JDBCService.class);	
        jdbcService.testTransactional();	
    }	
}

至此Deno工程搭建完毕,有需要源码的同学可以从下方地址获取


源码解析

可以看到我们的事务是通过EnableTransactionManagement注解启用的,所以此次源码解析也从此注解开始

@Target({ElementType.TYPE})	
@Retention(RetentionPolicy.RUNTIME)	
@Documented	
@Import({TransactionManagementConfigurationSelector.class})	
public @interface EnableTransactionManagement {	
    boolean proxyTargetClass() default false;	

	
    AdviceMode mode() default AdviceMode.PROXY;	

	
    int order() default 2147483647;	
}

相信看过我之前文章的同学都已经知道了@Import注解的原理了Spring @Import注解源码解析TransactionManagementConfigurationSelector

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {	
    public TransactionManagementConfigurationSelector() {	
    }	

	
    protected String[] selectImports(AdviceMode adviceMode) {	
        switch(adviceMode) {	
        case PROXY:	
            return new String[]{AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};	
        case ASPECTJ:	
            return new String[]{"org.springframework.transaction.aspectj.AspectJTransactionManagementConfiguration"};	
        default:	
            return null;	
        }	
    }	
}

可以看到这里是根据@EnableTransactionManagement注解的mode属性来确认注入哪一个配置类。这里由于我们没有指定属性,所以使用的默认的PROXY代理,走的是第一个分枝AutoProxyRegistrarProxyTransactionManagementConfiguration

创建自动代理的构建器

AutoProxyRegistrar类里面核心方法只有这一个

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) {	
          //由于咱们使用的默认PROXY所以走这个分支	
        AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);	
                  //强制使用Cglib动态代理	
        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));	
  }	
}

往下看

public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {	
       return registerAutoProxyCreatorIfNecessary(registry, (Object)null);	
   }	
  public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {	
       return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);	
   }	
   private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, 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);	
           if (!cls.getName().equals(apcDefinition.getBeanClassName())) {	
               int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());	
               int requiredPriority = findPriorityForClass(cls);	
               // 保存优先级高的构建器	
               if (currentPriority < requiredPriority) {	
                   apcDefinition.setBeanClassName(cls.getName());	
               }	
           }	
           return null;	
       }	
       // 如果容器中还没有自动代理构建器	
       // 则创建构建器相应的BeanDefinition对象 	
       RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);	
       beanDefinition.setSource(source);	
       beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);	
       beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);	

	
       // 向容器中注册代理构建器的BeanDefinition对象	
       registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);	
       return beanDefinition;	
   }

也就是说这一块的流程主要是为了注册org.springframework.aop.config.internalAutoProxyCreator这个bean

事务核心bean的构建

public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {	

	
  @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)	
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)	
  public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {	
    BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();	
    advisor.setTransactionAttributeSource(transactionAttributeSource());	
    advisor.setAdvice(transactionInterceptor());	
    if (this.enableTx != null) {	
      advisor.setOrder(this.enableTx.<Integer>getNumber("order"));	
    }	
    return advisor;	
  }	

	
  @Bean	
  @Role(BeanDefinition.ROLE_INFRASTRUCTURE)	
  public TransactionAttributeSource transactionAttributeSource() {	
    return new AnnotationTransactionAttributeSource();	
  }	

	
  @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;	
  }	

	
}

进入这个类之后可以看到这个类是一个配置类,这个类一共注册了三个bean,不要小瞧这三个bean,就是它们三个完成了整个Spring的事务功能

再仔细看的话会发现,AnnotationTransactionAttributeSourceTransactionInterceptor这两个bea又都注册到了BeanFactoryTransactionAttributeSourceAdvisor中,可以看出来这里是一个重点了

限于平台字数限制,本篇文章就到这里

640?wx_fmt=jpeg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值