事务的实现需要的配置
1.需要事务管理器
2.事务aop相关配置
2.事务aop相关配置
需要通知器 ( 切入点 + 通知) spring aop必备的
事务切入点PointCut : 匹配操作,主要是判断方法是否加上了事务@Transactional注解等一些判断
事务通知Advice: 执行代理对象的方法的时候执行的事务相关的通知操作
事务通知器Advisor: 事务切入点和事务通知的绑定
通知器advisor 的作用 :
获取切入点
getPointcut()
获取通知
getAdvice()
源码分析
首先肯定是看开启事务管理的注解,里面都配置了事务管理需要的相关类信息
@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 2147483647;
}
@Import({TransactionManagementConfigurationSelector.class})
进入TransactionManagementConfigurationSelector类
进入
ProxyTransactionManagementConfiguration类
可以看到和我们上面说的一样,首先创建事务的通知器
BeanFactoryTransactionAttributeSourceAdvisor advisor.setAdvice(this.transactionInterceptor());
接下来重点就是 事务的通知器里面的切入点 和 通知的如何实现了;
BeanFactoryTransactionAttributeSourceAdvisor 通知器
TransactionInterceptor 通知
TransactionAttributeSourcePointcut 切入点
1.进入aop后置处理器的后置方法 (事务基于aop实现的)
this.wrapIfNecessary(bean, beanName, cacheKey);
Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
List<Advisor> candidateAdvisors = this.findCandidateAdvisors();
从bean工厂里面找到所有的通知器对象 : candidateAdvisors
List<Advisor> eligibleAdvisors = this.findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
如果匹配的话,就放入通知器列表中
eligibleAdvisors.add(candidate);
canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions)
进行切入点里面的匹配的判断了
肯定要判断该方法是不是我们需要切入的方法拉,"所以事务这里主要是判断方法上面有没有加事务的注解 ",如果对象 有一个方法加了事务的注解, 这里匹配成功,返回true,就会加入通知器列表,aop后置处理器里面就会进行代理
tas.getTransactionAttribute
进行代理对象的创建 (spring 我的版本默认使用的是cglib进行代理的
通知Advice的调用
当调用事务方法的时候,就会进入代理对象的
intercept方法中
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
如果已经是
MethodInterceptor 类型 就直接add
下面的while是进行适配器--这里就先不管
接下来的重点就是把上面获取到的通知 进行执行了
链式 调用
this.invokeWithinTransaction(var10001, targetClass, invocation::proceed)
递归调用,继续调用process方法
完毕!!!!
事务aop就是这样完成的!!!!!!!!
总结
aop 1. 进行方法的切入 ,所以需要切入点 和 通知
Advice:通知,标识逻辑织入的位置,常见的有BeforeAdvice,AfterAdvice等。
PointCut:切入点,
1.标识对什么方法进入代理,常见的有JdkRegexpMethodPointcut根据正则表达式选取切入点,NameMatchMethodPointcut根据方法名选择切入点。
2.判断该方法是否需要织入逻辑
Advisor:通知器,是通知与切入点的集合。
通知器 Advisor 是由切入点 PointCut 和通知 Advice 构成的
aop 2.动态代理 , 返回代理对象,执行 定义的通知
通过aop注册的后置处理器,当bean对象生命周期执行到 bean的后置处理器的时候, 就会进入aop的后置方法 :
1.获取bean工厂里面的通知器对象
2. 判断当前bean对象的方法是否有匹配的通知器(切入点里面进行匹配);
3.如果当前bean对象有通知器列表 -> 动态代理
3.1 返回代理对象了,那肯定要执行通知了,
3.2 执行通知
4.如果当前bean对象没有通知器列表 直接返回当前bean对象
所以事务的实现
肯定就是需要通知器:切入点 + 通知了
下面说一下 Advice 和Interceptor 的关系
所以这里为啥可以直接把
TransactionInterceptor 设置到通知里面
在进行链式调用的时候, spring做了一个转换,把Advice 转为了Interceptor进行调用,
就是上面说的适配器
事务 这里是直接 实现
MethodInterceptor接口
所以就直接调用即可!!!!