最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring事務(wù)的開啟原理詳解

 更新時間:2021年03月22日 11:28:59   作者:檸檬時間  
這篇文章主要介紹了Spring事務(wù)的簡單實現(xiàn)步驟,幫助大家更好的理解和學(xué)習(xí)使用spring,感興趣的朋友可以了解下
  1. 在事務(wù)配置類上聲明@EnableTransactionManagement注解開啟事務(wù)
  2. 在事務(wù)配置類上定義數(shù)據(jù)源
  3. 在事務(wù)配置類上定義事務(wù)管理器
  4. 在相關(guān)類或者方法上使用@Transactional聲明事務(wù)

代碼如下:

@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開啟事務(wù)原理解析

@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來實現(xiàn)其注入,而TransactionManagementConfigurationSelector又主要使用selectImport方法來實現(xiàn)其注入,代碼如下:

@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());
 //根據(jù)AdviceMode返回不同的類型,默認(rèn)是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;
 }
}

其中主要功能點為根據(jù)AdviceMode選擇創(chuàng)建不同的bean,AdviceMode的默認(rèn)代理方式是PROXY,jdk代理。所以返回的是AutoProxyRegistrar和ProxyTransactionManagementConfiguration。

我們先分析AutoProxyRegistrar,AutoProxyRegistrar實現(xiàn)了ImportBeanDefinitionRegistrar,那在創(chuàng)建bean的時候會調(diào)用registerBeanDefinitions方法。registerBeanDefinitions方法的實現(xiàn):

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

總結(jié)

@EnableTransactionManagement利用AutoProxyRegistrar啟動Spring Aop,使用ProxyTransactionManagementConfiguration配置對應(yīng)切面部件。

以上就是Spring事務(wù)的簡單實現(xiàn)步驟的詳細(xì)內(nèi)容,更多關(guān)于Spring事務(wù)實現(xiàn)步驟的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • SpringBoot版本升級容易遇到的一些問題

    SpringBoot版本升級容易遇到的一些問題

    由于項目需求,需要將nacos 1.4.6版本升級到2.x版本,由此引發(fā)的springboot、springcloud、springcloud Alibaba一系列版本變更,本文給大家總結(jié)一下SpringBoot版本升級容易遇到的一些問題,需要的朋友可以參考下
    2023-12-12
  • 基于springboot創(chuàng)建mybatis的完整步驟

    基于springboot創(chuàng)建mybatis的完整步驟

    MyBatis是一款優(yōu)秀的數(shù)據(jù)庫持久層框架,相比Hibernate我更喜歡使用MyBatis,看的到SQL還是讓人更安心點,這篇文章主要給大家介紹了關(guān)于基于springboot創(chuàng)建mybatis的完整步驟,需要的朋友可以參考下
    2024-03-03
  • Java基礎(chǔ)學(xué)習(xí)之集合底層原理

    Java基礎(chǔ)學(xué)習(xí)之集合底層原理

    今天帶大家回顧Java基礎(chǔ)的相關(guān)知識,文中對集合底層原理作了非常詳細(xì)的圖文介紹,對Java初學(xué)者有非常好的幫助,需要的朋友可以參考下
    2021-05-05
  • Java操作ElasticSearch的實例詳解

    Java操作ElasticSearch的實例詳解

    Elasticsearch?是一個分布式的搜索和分析引擎,廣泛用于全文搜索、日志分析等場景,本文將介紹如何在?Java?應(yīng)用中使用?Elasticsearch?客戶端來連接和操作?Elasticsearch?集群,希望對大家有所幫助
    2025-01-01
  • JDBC編程實現(xiàn)文件、圖片的存儲方法

    JDBC編程實現(xiàn)文件、圖片的存儲方法

    這篇文章主要介紹了JDBC編程實現(xiàn)文件、圖片的存儲方法,以實例形式分析了Java基于JDBC操作數(shù)據(jù)庫的相關(guān)技巧,具有一定參考借鑒價值,需要的朋友可以參考下
    2015-10-10
  • java數(shù)組元素的引用實例講解

    java數(shù)組元素的引用實例講解

    在本篇文章里小編給大家整理的是一篇關(guān)于java數(shù)組元素的引用實例講解內(nèi)容,有需要的朋友們可以學(xué)習(xí)參考下。
    2021-03-03
  • Java線程阻塞方法sleep()與wait()的全面講解

    Java線程阻塞方法sleep()與wait()的全面講解

    這篇文章主要介紹了Java線程阻塞方法sleep()與wait()的全面講解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-02-02
  • 你一定不知道的Java Unsafe用法詳解

    你一定不知道的Java Unsafe用法詳解

    Unsafe是位于sun.misc包下的一個類,主要提供一些用于執(zhí)行低級別、不安全操作的方法,如直接訪問系統(tǒng)內(nèi)存資源、自主管理內(nèi)存資源等,下面這篇文章主要給大家介紹了關(guān)于Java Unsafe用法的相關(guān)資料,需要的朋友可以參考下
    2021-10-10
  • java圖形化界面實現(xiàn)簡單混合運算計算器的示例代碼

    java圖形化界面實現(xiàn)簡單混合運算計算器的示例代碼

    這篇文章主要介紹了java圖形化界面實現(xiàn)簡單混合運算計算器的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • java性能調(diào)優(yōu)System的gc垃圾回收方法

    java性能調(diào)優(yōu)System的gc垃圾回收方法

    這篇文章主要為大家介紹了java性能調(diào)優(yōu)System的gc垃圾回收方法示例解析有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03

最新評論

浦东新区| 修文县| 芒康县| 宾川县| 安吉县| 贵南县| 疏勒县| 定兴县| 三河市| 桃园市| 巧家县| 上高县| 绥芬河市| 康乐县| 凌云县| 瑞昌市| 扬州市| 外汇| 崇州市| 永年县| 隆回县| 沙田区| 年辖:市辖区| 锡林浩特市| 尼勒克县| 广丰县| 吉隆县| 涿州市| 赤壁市| 临桂县| 郯城县| 始兴县| 怀远县| 平江县| 珲春市| 兴宁市| 莆田市| 昭觉县| 莲花县| 东乡族自治县| 洛隆县|