Spring AOP源码深度剖析:简单几个注解就能控制事务?有这么神奇的吗?


声明式事务很方便,尤其纯注解模式,仅仅几个注解就能控制事务了

思考:这些注解都做了什么?好神奇!

@EnableTransactionManagement @Transactional

一、@EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
    
    

}

@EnableTransactionManagement 注解使用 @Import 标签 引用了 TransactionManagementConfigurationSelector类,这个类又向容器中导入了两个重要的组件


本文参考资料《Spring高级源码笔记》,需要的同学添加助理VX:C18173184271,备注一下CSDN+工作年限!免费获取

二、加载事务控制组件

  • AutoProxyRegistrar
    AutoProxyRegistrar 类registerBeanDefinitions 方法 中又注册了一个组件

    进入 AopConfigUtils.registerAutoProxyCreatorIfNecessary 方法

    发现最终,注册了一个叫做 InfrastructureAdvisorAutoProxyCreatorBean,而这个类是 AbstractAutoProxyCreator 的子类,实现了 SmartInstantiationAwareBeanPostProcessor 接口
public class InfrastructureAdvisorAutoProxyCreator extends
AbstractAdvisorAutoProxyCreator

public abstract class AbstractAdvisorAutoProxyCreator extends
AbstractAutoProxyCreator

public abstract class AbstractAutoProxyCreator extends
ProxyProcessorSupport
 	implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

继承体系结构图如下

它实现了SmartInstantiationAwareBeanPostProcessor,说明这是一个后置处理器,而且跟spring AOP 开启@EnableAspectJAutoProxy 时注册的 AnnotationAwareAspectJProxyCreator实现的是同一个接口,所以说,声明式事务springAOP 思想的一种应用

  • ProxyTransactionManagementConfiguration 组件
/*
* Copyright 2002-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package org.springframework.transaction.annotation;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Role;
import org.springframework.transaction.config.TransactionManagementConfigUtils;
import org.springframework.transaction.interceptor.BeanFactoryTransactionAttribut eSourceAdvisor;
import org.springframework.transaction.interceptor.TransactionAttributeSource;
import org.springframework.transaction.interceptor.TransactionInterceptor;

/**
* {@code @Configuration} class that registers the Spring infrastructure
beans
* necessary to enable proxy-based annotation-driven transaction
management.
*
* @author Chris Beams
* @since 3.1
* @see EnableTransactionManagement
* @see TransactionManagementConfigurationSelector
*/
@Configuration
public class ProxyTransactionManagementConfiguration extends
AbstractTransactionManagementConfiguration {
    
    
 
 	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
 	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
 	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(){
    
    
 		// 事务增强器
 		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
 		// 向事务增强器中注入 属性解析器 transactionAttributeSource
 		advisor.setTransactionAttributeSource(transactionAttributeSource());
 		// 向事务增强器中注入 事务拦截器 transactionInterceptor
 		advisor.setAdvice(transactionInterceptor());
 		if (this.enableTx != null) {
    
    
 			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
 		}
 		return advisor;
 	}
 	
 	@Bean
 	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
 	// 属性解析器 transactionAttributeSource
 	public TransactionAttributeSource transactionAttributeSource() {
    
    
 		return new AnnotationTransactionAttributeSource();
 	}
	@Bean
 	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
 	// 事务拦截器 transactionInterceptor
 	public TransactionInterceptor transactionInterceptor() {
    
    
 		TransactionInterceptor interceptor = new TransactionInterceptor();
 
		interceptor.setTransactionAttributeSource(transactionAttributeSource());
 		if (this.txManager != null) {
    
    
 			interceptor.setTransactionManager(this.txManager);
 		}
 		return interceptor;
 	} 
}

ProxyTransactionManagementConfiguration是一个容器配置类,注册了一个组件 transactionAdvisor,称为 事务增强器 ,然后在这个事务增强器中又注入了两个属性: transactionAttributeSource,即 属性解析器 transactionAttributeSource事务拦截器 transactionInterceptor

  • 属性解析器 AnnotationTransactionAttributeSource 部分源码如下


属性解析器有一个成员变量是 annotationParsers,是一个集合,可以添加多种注解解析器
(TransactionAnnotationParser),我们关注 Spring 的注解解析器,部分源码如下

属性解析器的作用之一就是用来解析 @Transaction注解

  • TransactionInterceptor 事务拦截器,部分源码如下

  • 上述组件如何关联起来的?
    • 事务拦截器实现了 MethodInterceptor接口,追溯一下上面提到的 InfrastructureAdvisorAutoProxyCreator 后置处理器,它会在代理对象执行目标方法的时候获取其拦截器链,而拦截器链就是这个TransactionInterceptor,这就把这两个组件联系起来;
    • 构造方法传入PlatformTransactionManager(事务管理器)、TransactionAttributeSource(属性解析器),但是追溯一下上面贴的ProxyTransactionManagementConfiguration的源码,在注册事务拦截器的时候并没有调用这个带参构造方法,而是调用的无参构造方法,然后再调用set方法注入这两个属性,效果一样。
  • invokeWithinTransaction 方法,部分源码如下(关注1、2、3、4 标注处)


如果你需要这份完整版的《Spring高级源码笔记》,只需你多多支持我这篇文章。

多多支持,即可免费获取资料——三连之后(承诺:100%免费)

快速入手通道:添加助理VX:C18173184271,备注一下CSDN+工作年限! 免费获取!诚意满满!!!

猜你喜欢

转载自blog.csdn.net/Java_Caiyo/article/details/113180674
今日推荐