Spring事务的开启原理详解

目录@EnableTransactionManagement开启事务原理解析总结

    在事务配置类上声明@EnableTransactionManagement注解开启事务 在事务配置类上定义数据源 在事务配置类上定义事务管理器 在相关类或者方法上使用@Transactional声明事务

代码如下:

@Configuration@EnableTransactionManagementpublic class RootConfig{  @Bean public DataSource dataSource(){  DruidDataSource dataSource = new DruidDataSource();  dataSource.setXXX();  ...    return dataSource; }  @Bean public PlatfromTransactionManager txManager(){  return new DataSourceTransactionManager(dataSource()); }}
@Servicepublic class UserService{ @Autowired private UserRepository userRepository;  @Transactional public void addUser(User user){  userRepository.save(user); }}

@EnableTransactionManagement开启事务原理解析

@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 Ordered.LOWEST_PRECEDENCE;}

可以看到,@EnableTransactionManagement接口类主要Import了TransactionManagementConfigurationSelector来实现其注入,而TransactionManagementConfigurationSelector又主要使用selectImport方法来实现其注入,代码如下:

@Overridepublic final String[] selectImports(AnnotationMetadata importingClassMetadata) { Class<?> annoType = GenericTypeResolver.resolveTypeArgument(getClass(), AdviceModeImportSelector.class); AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(importingClassMetadata, annoType); if (attributes == null) {  throw new IllegalArgumentException(String.format(   "@%s is not present on importing class '%s' as expected",   annoType.getSimpleName(), importingClassMetadata.getClassName())); } AdviceMode adviceMode = attributes.getEnum(this.getAdviceModeAttributeName()); //根据AdviceMode返回不同的类型,默认是AdviceMode.PROXY。 String[] imports = selectImports(adviceMode); if (imports == null) {  throw new IllegalArgumentException(String.format("Unknown AdviceMode: '%s'", adviceMode)); } return imports;}@Overrideprotected 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; }}

其中主要功能点为根据AdviceMode选择创建不同的bean,AdviceMode的默认代理方式是PROXY,jdk代理。所以返回的是AutoProxyRegistrar和ProxyTransactionManagementConfiguration。

我们先分析AutoProxyRegistrar,AutoProxyRegistrar实现了ImportBeanDefinitionRegistrar,那在创建bean的时候会调用registerBeanDefinitions方法。registerBeanDefinitions方法的实现:

@Overridepublic 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;   //只有@EnableTransactionManagement注解才会走到这里   if (mode == AdviceMode.PROXY) {    AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);    if ((Boolean) proxyTargetClass) {     AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);     return;    }   }  } } //...}public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) { return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);}

可以看到,它通过注册InfrastructureAdvisorAutoProxyCreator来启动Spring Aop。

接下来再看ProxyTransactionManagementConfiguration的作用,代码如下:

@Configurationpublic 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());  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; }}

ProxyTransactionManagementConfiguration是一个配置文件,注册了三个bean,BeanFactoryTransactionAttributeSourceAdvisor、AnnotationTransactionAttributeSource、TransactionInterceptor,而这三个类分别继承Advisor、Advice和Pointcut。即切面所需组件。

总结

@EnableTransactionManagement利用AutoProxyRegistrar启动Spring Aop,使用ProxyTransactionManagementConfiguration配置对应切面部件。

以上就是Spring事务的简单实现步骤的详细内容,更多关于Spring事务实现步骤的资料请关注其它相关文章!

“人”的结构就是相互支撑,“众”人的事业需要每个人的参与。

Spring事务的开启原理详解

相关文章:

你感兴趣的文章:

标签云: