91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Spring事務開啟原理的示例分析

發布時間:2021-03-22 12:35:38 來源:億速云 閱讀:150 作者:小新 欄目:開發技術

這篇文章給大家分享的是有關Spring事務開啟原理的示例分析的內容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。

  1. 在事務配置類上聲明@EnableTransactionManagement注解開啟事務

  2. 在事務配置類上定義數據源

  3. 在事務配置類上定義事務管理器

  4. 在相關類或者方法上使用@Transactional聲明事務

代碼如下:

@Configuration
@EnableTransactionManagement
public class RootConfig{
 
 @Bean
 public DataSource dataSource(){
  DruidDataSource dataSource = new DruidDataSource();
  dataSource.setXXX();
  ...
  
  return dataSource;
 }
 
 @Bean
 public PlatfromTransactionManager txManager(){
  return new DataSourceTransactionManager(dataSource());
 }
}
@Service
public 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方法來實現其注入,代碼如下:

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

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

其中主要功能點為根據AdviceMode選擇創建不同的bean,AdviceMode的默認代理方式是PROXY,jdk代理。所以返回的是AutoProxyRegistrar和ProxyTransactionManagementConfiguration。

我們先分析AutoProxyRegistrar,AutoProxyRegistrar實現了ImportBeanDefinitionRegistrar,那在創建bean的時候會調用registerBeanDefinitions方法。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;
   //只有@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的作用,代碼如下:

@Configuration
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());
  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。即切面所需組件。

感謝各位的閱讀!關于“Spring事務開啟原理的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

庆城县| 金秀| 茶陵县| 高台县| 涿鹿县| 马公市| 康乐县| 剑阁县| 云霄县| 磴口县| 阳西县| 怀来县| 延安市| 东辽县| 凤山市| 泰州市| 广东省| 仁布县| 肇东市| 南昌市| 常德市| 文山县| 定边县| 丹东市| 巴林左旗| 如皋市| 泗洪县| 镇赉县| 华阴市| 中西区| 甘肃省| 奎屯市| 贵州省| 酒泉市| 六安市| 磐石市| 尼玛县| 峡江县| 肃北| 临邑县| 石河子市|