当前位置:首页 > Java技术 > springboot 事务aop自动配置

springboot 事务aop自动配置

2022年09月16日 23:19:49Java技术16
  1. 自动配置类org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration
    配置类代码不贴了,但配置类中有个重要的注解是一定要的@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;

}

配置选择器类TransactionManagementConfigurationSelector 关于Selector 是怎么导入配置的看我的博客

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
     

	/**
	 * Returns {@link ProxyTransactionManagementConfiguration} or
	 * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
	 * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
	 * respectively.
	 */
	@Override
	protected String[] selectImports(AdviceMode adviceMode) {
     
		switch (adviceMode) {
     
			case PROXY:
			  // 这两个类会被导入(重要)
				return new String[] {
     AutoProxyRegistrar.class.getName(),
						ProxyTransactionManagementConfiguration.class.getName()};
			case ASPECTJ:
				return new String[] {
     determineTransactionAspectClass()};
			default:
				return null;
		}
	}

	private String determineTransactionAspectClass() {
     
		return (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader()) ?
				TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
				TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
	}

}
  1. AutoProxyRegistrar 注册InfrastructureAdvisorAutoProxyCreator
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
     
		boolean candidateFound = false;
		Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
		for (String annType : annTypes) {
     
			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
			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) {
     
				    // 注册 InfrastructureAdvisorAutoProxyCreator 
					AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
					if ((Boolean) proxyTargetClass) {
     
						AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
						return;
					}
				}
			}
		}
		if (!candidateFound && logger.isInfoEnabled()) {
     
			String name = getClass().getSimpleName();
			logger.info(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, null);
	}



@Nullable
	public static BeanDefinition registerAutoProxyCreatorIfNecessary(
			BeanDefinitionRegistry registry, @Nullable Object source) {
     

		return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
	}
  1. InfrastructureAdvisorAutoProxyCreator 实现了接口BeanPostProcessorpostProcessAfterInitialization 方法
    spring 在生成bean 时调用到org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean 方法,该方法内就会调用到接口BeanPostProcessorpostProcessAfterInitialization 方法

InfrastructureAdvisorAutoProxyCreator 对方法postProcessAfterInitialization的实现如下, 就进入到aop代理创建过程

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
     
		if (bean != null) {
     
			Object cacheKey = getCacheKey(bean.getClass(), beanName);
			if (this.earlyProxyReferences.remove(cacheKey) != bean) {
     
			   // 创建代理对象
				return wrapIfNecessary(bean, beanName, cacheKey);
			}
		}
		return bean;
	}

  1. TransactionManagementConfigurationSelector 类还导入了一个类ProxyTransactionManagementConfiguration
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
     

	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
			TransactionAttributeSource transactionAttributeSource,
			TransactionInterceptor transactionInterceptor) {
     
		// 创建advisor, advisor  会在bean 初始化时在
		//AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization方法内
		//通过调用InfrastructureAdvisorAutoProxyCreator#postProcessBeforeInstantiation调用创建aop代理
		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
		advisor.setTransactionAttributeSource(transactionAttributeSource);
		//  设置事务拦截器
		advisor.setAdvice(transactionInterceptor);
		if (this.enableTx != null) {
     
			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
		}
		return advisor;
	}

  //TransactionAttributeSource 包含解析器,  解析@Transactional注解中的信息
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionAttributeSource transactionAttributeSource() {
     
		return new AnnotationTransactionAttributeSource();
	}

  //  配置事务拦截器
	@Bean
	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
	public TransactionInterceptor transactionInterceptor(
			TransactionAttributeSource transactionAttributeSource) {
     
		TransactionInterceptor interceptor = new TransactionInterceptor();
		interceptor.setTransactionAttributeSource(transactionAttributeSource);
		if (this.txManager != null) {
     
			interceptor.setTransactionManager(this.txManager);
		}
		return interceptor;
	}

}

从代码可以看出ProxyTransactionManagementConfiguration 配置类配置了三个bean

  • BeanFactoryTransactionAttributeSourceAdvisor advisor 会在bean 初始化时在AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization方法内通过调用InfrastructureAdvisorAutoProxyCreator#postProcessBeforeInstantiation创建aop代理
  • TransactionAttributeSource 包含解析器, 解析@Transactional注解中的信息
  • TransactionInterceptor 在代理bean 中实际对事务进行拦截

参考博客

作者:tszxlzc
来源链接:https://blog.csdn.net/tszxlzc/article/details/104261369

版权声明:
1、JavaClub(https://www.javaclub.cn)以学习交流为目的,由作者投稿、网友推荐和小编整理收藏优秀的IT技术及相关内容,包括但不限于文字、图片、音频、视频、软件、程序等,其均来自互联网,本站不享有版权,版权归原作者所有。

2、本站提供的内容仅用于个人学习、研究或欣赏,以及其他非商业性或非盈利性用途,但同时应遵守著作权法及其他相关法律的规定,不得侵犯相关权利人及本网站的合法权利。
3、本网站内容原作者如不愿意在本网站刊登内容,请及时通知本站(javaclubcn@163.com),我们将第一时间核实后及时予以删除。


本文链接:https://www.javaclub.cn/java/42150.html

分享给朋友:

“springboot 事务aop自动配置” 的相关文章

spring boot配置事务(事务回滚)

spring boot配置事务(事务回滚)

在业务层(service)中难免存在要先后操作多张表的业务逻辑,如前端完成一个操作,后台需要对数据库三张表进行操作,如若任意一个操作事务,这几个操作都应该不允许被实现,即回到操作前,解决方法是开启事务,让其在出错时实现事务回滚作用。 如:有以下三个...

SpringBoot中添加事务

今天项目中需要使用到事务,所以在这里将SpringBoot的事务实现方式学习一下 SpringBoot中使用事务会使用到@Transactional这个注解来实现   先来对Transactional注解有个大致了解   1.其上注解...

springboot 事务统一配置

什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合。由于数据操作在顺序执行的过程中,任何一步操作都有可能发生异常,异常会导致后续操作无法完成,此时由于业务逻辑并未正确的完成,之前成功操作数据的并不可靠,需要在这种情况下进行...

springboot MongoDB 事务

前言 有玩过mongodb的朋友大概会知道mongodb4.0版本已经可以支持多文档副本集事务。而最新版本4.2更是支持分片事务,即真正的支持分布式事务。不过当时我使用mongodb,其最新版本为4.10,4.2版本还没发布,因此本文还是以4.0版本的副本集事务来讲解。...

springboot 默认事务 代码示例

springboot 默认事务 代码示例

springboot 默认事务 代码示例 Ⅰ同一个类内默认传播行为的调用 1.1 方法addTeacher带默认传播行为的事务调用没事务的方法updateTeacher @Transactional(propagation = Pro...

SpringBoot多数据源配置事务

在多数据源中配置事务,其实对于SpringBoot来很简单,当然这个的前提是首先把多数据源都配好的情况下,如果不会多数据源配置,请看该系列 SpringBoot整合多数据源 首先在启动类配置 @SpringBootApplication @E...

SpringBoot jpa事务注解详解

SpringBoot jpa事务注解详解

@Transactional spring 事务注解 1.简单开启事务管理 @EnableTransactionManagement // 启注解事务管理,等同于xml配置方式的 <tx:annotation-driven /> 2.事务注解详...

浅谈SpringBoot事务处理

浅谈SpringBoot事务处理

什么是事务 所有数据访问技术都有事务机制,这些技术提供了API来开启事务、提交事务完成数据操作,或者在发生错误的时候回滚数据。 Spring采用统一的机制来处理不同的数据访问技术的事务,Spring的事务提供一个 PlatformTransactionManager...

springBoot service 事务注解@Transactional不起作用的解决

在springBoot使用事物时,发现事务并没有正常执行,没有进行回滚 @Transactional public void add(String companyName,String name) throws MyException{ compan...

SpringBoot非官方教程 | 第七篇:springboot开启声明式事务

SpringBoot非官方教程 | 第七篇:springboot开启声明式事务

转载请标明出处: http://blog.csdn.net/forezp/article/details/70833629 本文出自方志朋的博客 springboot开启事务很简单,只需要一个注解@Transactional 就可以了。因为...

发表评论

访客

◎欢迎参与讨论,请在这里发表您的看法和观点。