欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

 更新時(shí)間:2021年03月22日 11:28:59   作者:檸檬時(shí)間  
這篇文章主要介紹了Spring事務(wù)的簡單實(shí)現(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來實(shí)現(xiàn)其注入,而TransactionManagementConfigurationSelector又主要使用selectImport方法來實(shí)現(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;
 }
}

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

我們先分析AutoProxyRegistrar,AutoProxyRegistrar實(shí)現(xiàn)了ImportBeanDefinitionRegistrar,那在創(chuàng)建bean的時(shí)候會調(diào)用registerBeanDefinitions方法。registerBeanDefinitions方法的實(shí)現(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是一個(gè)配置文件,注冊了三個(gè)bean,BeanFactoryTransactionAttributeSourceAdvisor、AnnotationTransactionAttributeSource、TransactionInterceptor,而這三個(gè)類分別繼承Advisor、Advice和Pointcut。即切面所需組件。

總結(jié)

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

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

相關(guān)文章

  • 淺談java面向?qū)ο笾兴姆N權(quán)限

    淺談java面向?qū)ο笾兴姆N權(quán)限

    這篇文章主要介紹了淺談java面向?qū)ο笾兴姆N權(quán)限,具有一定借鑒價(jià)值,需要的朋友可以參考下。
    2017-12-12
  • java實(shí)現(xiàn)水果超市管理系統(tǒng)

    java實(shí)現(xiàn)水果超市管理系統(tǒng)

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)水果超市管理系統(tǒng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01
  • java基于Socket做一個(gè)簡單下載器

    java基于Socket做一個(gè)簡單下載器

    這篇文章主要為大家詳細(xì)介紹了java如何基于Socket制作一個(gè)簡單下載器,感興趣的小伙伴們可以參考一下
    2016-08-08
  • java使用this調(diào)用構(gòu)造函數(shù)的實(shí)現(xiàn)方法示例

    java使用this調(diào)用構(gòu)造函數(shù)的實(shí)現(xiàn)方法示例

    這篇文章主要介紹了java使用this調(diào)用構(gòu)造函數(shù)的實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了java面向?qū)ο蟪绦蛟O(shè)計(jì)中函數(shù)調(diào)用相關(guān)操作技巧,需要的朋友可以參考下
    2019-08-08
  • Elasticsearch配置文件示例示范

    Elasticsearch配置文件示例示范

    這篇文章主要為大家介紹了Elasticsearch配置文件的示例示范,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-04-04
  • 詳解Java中@Override的作用

    詳解Java中@Override的作用

    這篇文章主要介紹了詳解Java中@Override的作用的相關(guān)資料,希望通過本文能幫助到大家,讓大家理解這部分內(nèi)容,需要的朋友可以參考下
    2017-10-10
  • java實(shí)現(xiàn)簡單中國象棋

    java實(shí)現(xiàn)簡單中國象棋

    這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)簡單中國象棋,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-05-05
  • 深入了解Java核心類庫--String類

    深入了解Java核心類庫--String類

    這篇文章主要為大家詳細(xì)介紹了java String類定義與使用的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能給你帶來幫助
    2021-07-07
  • JVM創(chuàng)建對象及訪問定位過程詳解

    JVM創(chuàng)建對象及訪問定位過程詳解

    這篇文章主要介紹了JVM創(chuàng)建對象及訪問定位過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-12-12
  • Springboot自動掃描包路徑來龍去脈示例詳解

    Springboot自動掃描包路徑來龍去脈示例詳解

    這篇文章主要介紹了Springboot自動掃描包路徑來龍去脈示例詳解,本文通過示例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-12-12

最新評論