声明式事务测试 :Spring注解笔记系列(一)

一、序言

1、为何写?

好记性不如烂笔头。

2、写来何用?

温故而知新,你懂得。

3、有谁看?

本系列笔记可作为阅读《Think In Java》辅助理解,人不可止步,圈地自封。

二、环境搭建

(1) 导入相关依赖(数据源、数据库驱动、Spring-jdbc模块)
(2) 配置数据源,JdbcTemplate(Spring提供的简化数据库操作工具)操作数据
(3) 给方法加上标注@Transactional 表示当前方法是一个事务方法
(4) @EnableTransactionManagement 开启基于注解的事务管理功能 
(5) 配置事务管理器来控制事务

三、@Transactional

(1) 方法加上该注解则说明:表示当前方法是一个事务方法

四、@EnableTransactionManagement

(1) 开启基于注解的事务管理功能

(2) 原理

EnableTransactionManagement使用Import导入了TransactionManagementConfigurationSelector(继承的是ImportSelector)类,给容器中导入两个组件

 A、使用selectImports(AdviceMode adviceMode)方法(AdviceMode就是该注解里定义的adviceMode属性且默认就是proxy)判断如果是PROXY,则返回String数组(AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()),如果是AspectJ则返回String数组(TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME)

B、AutoProxyRegistrar其实就是给容器中注册Bean的(ImportBeanDefinitionRegistrar),调用ImportBeanDefinitionRegistrar(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) 给容器中注册Bean

1、判断如果是proxy,则使用AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);,并且设置了proxyTargetClass,
则会Object proxyTargetClass = candidate.get("proxyTargetClass");,其中proxyTargetClass就是该注解中定义的值(如果它为true,但是默认为false)

1.1、proxy且不等于true,调用registerAutoProxyCreatorIfNecessary(registry)。首先创建一个自动代理创建器(registerAutoProxyCreatorIfNecessary) 创建器会调用如需创建器(registerAutoProxyCreatorIfNecessary(registry, null)),如需创建器会调用需要器(registerOrEscalateApcAsRequired()), 需要器会创建一个组件(InfrastructureAdvisorAutoProxyCreator) 给容器中注册一个组件InfrastructureAdvisorAutoProxyCreator(后置处理器)

1.2、InfrastructureAdvisorAutoProxyCreator利用后置处理器机制在对象创建之后,返回一个代理对象(其中有增强器),代理对象执行方法利用拦截器链进行调用

C、ProxyTransactionManagementConfiguration作用

1、给容器中注册事务增强器

1.1、事务增强器要用事务注解的信息:AnnotationTransactionAttributeSource解析事务注解
1.2、事务拦截器:TransactionInterceptor保存了事务属性的信息,事务管理器(该类为方法拦截器)
               方法拦截器:比如容器中有一个代理对象,代理对象要执行目标方法,方法拦截器就会进行工作
1.3、AOP中四个通知方法最终都被整合成事务增强器,增强器变为MethodInterceptor

2、MethodInterceptor如何工作

2.1、在目标执行的时候,因为是代理对象在执行,由于代理对象会执行拦截器链(MethodInterceptor)  
2.2、事务拦截器:先获取事务相关的一些属性,再来获取PlateformTransactionManager,如果事先没有添加任何指定TransactionManager,最终会从容器中按照类型获取一个PlateformTransactionManager
2.3、目标方法先执行,如果异常,获取到事务管理器,并利用其进行回滚。如果正常,利用事务管理器提交事务

 

(由于重装系统后代码不慎丢失,如需参考,找回后我将上传github,仅供参考)

你可能感兴趣的:(Spring注解)