springboot @Transactional事务原理源码

springboot事务必要组件和过程:

1.注册事务管理器DatasouceTransactionManager

2.注册事务增强器BeanFactoryTransactionAttributeSourceAdvisor,里面包含事务拦截器TransactionInterceptor

3.注册事务注解解析用的后置处理器AnnotationAwareAspectJAutoProxyCreator,里面用来生成代理对象

4.通过代理对象调用方法,会先走代理对象的invoke()方法,通过事务拦截器来开启事务,执行目标方法,提交或回滚事务

一、注入BeanFactoryTransactionAttributeSourceAdvisor和TransactionInterceptor和DatasouceTransactionManager

1.注册DatasouceTransactionManager

通过springboot的spi机制,在DataSourceTransactionManagerAutoConfiguration中的DataSourceTransactionManagerConfiguration中,通过@Bean的方式注入了DataSourceTransactionManager到spring容器

2.注入BeanFactoryTransactionAttributeSourceAdvisor和TransactionInterceptor

扫描spring-boot-autoconfigure依赖包下的META-INF/spring.factories,加载文件里的TransactionAutoConfiguration类,可以看到sringboot在2.0之后默认使用了cglib代理,下面将的是jdk的代理,原理是一样的

解析TransactionAutoConfiguration类里的@EnableTransactionManagement注解,根据该注解上的@Import加载TransactionManagementConfigurationSelector类

通过TransactionManagementConfigurationSelector类的selectImports方法加载ProxyTransactionManagementConfiguration类

ProxyTransactionManagementConfiguration类通过@Bean加载BeanFactoryTransactionAttributeSourceAdvisor类,该类实现了Pointcut,并且在该类里注入了实现了Advise接口的TransactionInterceptor类,TransactionInterceptor就是事务拦截器。

这里setTransactionManager其实是一个null,后面拿事务管理器时是从单例池中拿,不是用的这个。

另外要提一点的是很多类中之所以可以用到BeanFactory(DefaultListableBeanFactory),是因为实现了BeanFactoryAware,spring在初始化bean的时候会将beanFactory设置进去

二、注入AnnotationAwareAspectJAutoProxyCreator切面解析处理器

通过spi机制自动装载AopAutoConfiguration类,加载AopAutoConfiguration类,根据proxyTargetClass配置来选择是使用jdk的proxy还是cglib来生成动态代理类,截图如下:

解析@EnableAspectJAutoProxy注解,通过该注解上的@Import加载AspectJAutoProxyRegistrar类

AspectJAutoProxyRegistrar类会向Spring容器注册AnnotationAwareAspectJAutoProxyCreator类,该类实现了BeanPostProcessor接口,所以这个aop逻辑是在Springbean生成过程中通过后置处理器逻辑来实现的。

AnnotationAwareAspectJAutoProxyCreator继承AspectJAwareAdvisorAutoProxyCreator继承AbstractAdvisorAutoProxyCreator继承AbstractAutoProxyCreator实现BeanFactoryAware,

因为AnnotationAwareAspectJAutoProxyCreator最顶层实现了BeanFactoryAware所以初始化时需要调用AbstractAdvisorAutoProxyCreator的setBeanFactory方法,就会走下图的逻辑,就会走this.initBeanFactory逻辑,

其实就是调用了子类AnnotationAwareAspectJAutoProxyCreator的initBeanFactory方法,然后调用super.initBeanFactory方法

也就是调用了AbstractAdvisorAutoProxyCreator的initBeanFactory方法,这个方法里面初始化了this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);

后面会有一句代码叫this.advisorRetrievalHelper.findAdvisorBeans()。所以要知道this.advisorRetrievalHelper就是在这里初始化的

三、事务注解解析和代理生成过程

前面的步骤暂时省略了,这里只分析从开始走后置处理器的逻辑

AnnotationAwareAspectJAutoProxyCreator

执行AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator的postProcessAfterInitialzation方法

this.wrapIfNecessary()方法就是要进行生成代理了

this.getAdvicesAndVisorsForBean调用的是AbstractAutoProxyCreator子类AbstractAdvisorAutoProxyCreator中的

ProxyTransactionManagementConfiguration中通过@Bean注册的BeanFactoryTransactionAttributeSourceAdvisor名称就叫做"org.springframework.transaction.config.internalTransactionAdvisor",所以下面传入一个DefaultListableBeanFactory和Avisor.class,从spring容器中查找Avisor类型的bean,然后获取它们的名称,advisorNames就包含了"org.springframework.transaction.config.internalTransactionAdvisor",下面就通过name和Advisor.class获取对应的BeanFactoryTransactionAttributeSourceAdvisor事务增强器

那么candidateAdvisors中包含从spring容器中获取出来的所有增强器,candidateAdvisors之所以是一个集合,是因为容器中是Advisor.class类型的bean可能不止是BeanFactoryTransactionAttributeSourceAdvisor,下图中就是还有一个Druid连接池sql监控的增强器

然后通过传入目标beanName和beanClass筛选出属于本类需要的增强器,如果你的类或者方法上有@Transactional注解,那么返回的eligibleAdvisors中就有BeanFactoryTransactionAttributeSourceAdvisor,

AopUtils#canApply(Pointcut, Class , boolean) 方法中会调用到 TransactionAttributeSourcePointcut#matches 方法

BeanFactoryTransactionAttributeSourceAdvisor继承了PoincutAdvisor

canApply中会调用BeanFactoryTransactionAttributeSourceAdvisor.getPointCut()返回一个TransactionAttributeSourcePointcut

然后pointcut再调用getMethodMatcher()返回一个MethodMatcher也就是TransactionAttributeSourcePointcut自己,因为getMethodMatcher()是在父类StaticMethodMatcherPointcut中调用的,而父类StaticMethodMatcherPointcut继承了StaticMethodMatcher继承了MethodMatcher,所以TransactionAttributeSourcePointcut也是一个MethodMatcher。

TransactionAttributeSourcePointcut#getTransactionAttributeSource 返回的是:AnnotationTransactionAttributeSource 实例,AnnotationTransactionAttributeSource继承自:AbstractFallbackTransactionAttributeSource, 故此TransactionAttributeSourcePointcut#matches 最终会调用到 AbstractFallbackTransactionAttributeSource#getTransactionAttribute 方法

SringTransactionAnnotationParser实在下图中被创建的

以上是this.getAdvicesAndAdvisorForBean方法内部调用过程,调用完该方法出来后,回到下图中创建代理对象this.createProxy

Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);返回指定的拦截器

this.createAopProxy就是创建一个JdkDynamicAopProxy代理对象(jdk代理为例子),JdkDynamicAopProxy继承了InvocationHandler

那么将来通过controller调用某个service的某个加了@Transactional的方法,就会首先进入invoke方法进行拦截

invoke方法中会执行下面一段,chain就是根据method把所需要的拦截器拿出来,因为拦截器已经在之前的操作this.createAopProxy中设置进了成员属性advised,所以这里可以通过this.advised.getInterceptorsAndDynamicInterceptionAdvice拿出来,例如method加了@Transactional,那么chain中就会包含BeanFactoryTransactionAttributeSourceAdvisor#TransactionInterceptor。如果说chain是空的,那么就会直接通过反射调用原始bean的方法,那就没有事务。

下面调用的就是拦截器的invoke方法

那么其中的一个拦截器TransactionInterceptor的invoke方法就会被调用,就是开启事务的逻辑了,逻辑如下

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值