Spring AOP 之 Transantion

我们表达这个概念的时候,我也希望大家能够来按照两个部分来介绍:第一部分代理创建,第二我们的调用过程,尤以,TransactionInfo,还有我们的这个createTransactionIfNecessary最为重要。

1. 利用注解@EnableTransactionManagement导入了@Import(TransactionManagementConfigurationSelector.class)

开启事物

@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {}

2. TransactionManagementConfigurationSelector实现了ImportSelector接口,会被ConfigurationClassPostProcessor类进行解析

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {

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

}

①. TransactionManagementConfigurationSelector导入两个核心类

  ○ AutoProxyRegistrar
  ○ ProxyTransactionManagementConfiguration

1. AutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,也会被ConfigurationClassPostProcessor类解析

默认为AdviceMode.PROXY

// 根据@EnableTransactionManagement注解的属性,
// 来导入InfrastructureAdvisorAutoProxyCreator,
// 用于创建事务代理的 BeanPostProcessor
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {


	boolean proxyTargetClass() default false;
        // 增强模式:AdviceMode.PROXY
	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;

}

用于创建事物代理的BeanPostProcessor

public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
    // 用于创建事物代理的BeanPostProcessor
    return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
}

1. InfrastructureAdvisorAutoProxyCreator继承自AbstractAutoProxyCreator(和AnnotationAwareAspectJAutoProxyCreator(用于处理AOP的BeanPostProcessor)一样)

image

2. ProxyTransactionManagementConfiguration是被TransactionManagementConfigurationSelector导入的配置类

 1. ProxyTransactionManagementConfiguration是一个配置类,被@Configuration标注了
 2. transactionAdvisor这个方法,创建的是 事物切面Bean,也就是Advisor
 3. transactionAttributeSource这个方法,切入点在事务配置中,切入点的表现形式?事务属性形式表达由transactionAtrributesSource 体现
 4. transactionInterceptor,额外功能TransactionInterceptor体现 额外功能 里面包装TransactionManager

配置类

@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());
		if (this.enableTx != null) {
			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;
	}

}

3. 执行sql操作的流程,会由InfrastructureAdvisorAutoProxyCreator这个BeanPostProcessor创建的代理类进行操作

被事物控制的方法

public class TestAnnotationTx {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
        UserService userService = (UserService) ctx.getBean("userServiceImpl");

        User user = new User();
        user.setName("sunshuai");
        user.setVers(1);

        userService.register(user);
    }
}
  ○ 代码中的userService是被代理的类
  ○ 调用userService.register(user)方法时,会进行aop事物增强
  ○ 会在createTransactionIfNecessary方法中,根据事物属性(隔离、传播、只读、超时、异常)进行判断,是否创建事物

1. Spring利用AOP控制事物,封装了一个类:TransactionInfo

// 事物管理器
private final PlatformTransactionManager transactionManager;
// 包含了 1.切入点 2.额外功能
private final TransactionAttribute transactionAttribute;
// 切点:被事物控制的方法
private final String joinpointIdentification;
// 记录当前事务的状态
// 是否是一个新的事务
// 是否是只读的事务
// 是否开启同步(隔离性)
// 挂起资源
private TransactionStatus transactionStatus;
// 外部(老的)的事物信息
private TransactionInfo oldTransactionInfo;
posted @ 2024-01-25 10:38  zzusjw  阅读(27)  评论(0)    收藏  举报