https://blog.csdn.net/c_unclezhang/article/details/78769426
从代码中可以看出,事务的开始一切都从:AnnotationDrivenBeanDefinitionParser 类的parse开始了
AOP入口,AspectJAutoProxyBeanDefinitionParser,作为核心接口BeanDefinitionParser的一个实现类
一、调用parse,解析beanDefinition
1.调用registerAspectJAnnotationAutoProxyCreatorIfNecessary
2.对于AOP的实现,基本是靠AnnotationAwareAspectJAutoProxyCreator去完成的,它可以根据@point注解定义的切点来代理相匹配的bean。
3.调用registry.getBeanDefinition,也就是从beanDefinitionMap中获取已经注册好的bean
4.获取注册好的beanDefinition后,调用registerComponentIfNecessary注册这个组件,并且通知监听器
解析tx事务的标签的核心全部在InfrastructureAdvisorAutoProxyCreator这个里面,
InfrastructureAdvisorAutoProxyCreator -> AbstractAdvisorAutoProxyCreator -> AbstractAutoProxyCreator
所有的解析工作大部分都在AbstractAutoProxyCreator类里面解析完成的。前面已经分析了aop时已经分析完毕了,所以在这里就不继续分析了。
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
二、上面已经完成了,根据注解,从beanDefinitionMap中获取已经注册的beanDefinition出来,下面就开始创建aop代理
2.1 继续调用wrapIfNecessary,重点逻辑在getAdvicesAndAdvisorsForBean
这个方法会提取当前bean 的所有增强方法,然后获取到适合的当前bean 的增强方法,然后对增强方法进行排序,最后返回
2.2 获取到当前bean的增强方法后specificInterceptors
便调用createProxy方法,创建代理。
2.3 先创建代理工厂proxyFactory,然后获取当前bean 的增强器advisors,把当前获取到的增强器添加到代理工厂proxyFactory。
然后设置当前的代理工的代理目标对象为当前bean,最后根据配置创建JDK的动态代理工厂,或者CGLIB的动态代理工厂,然后返回proxyFactory
2.4
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
三、根据目标类targetClass判断,创建Aop
3.1 如果targetClass是接口,就创建一个JdkDynamicAopProxy
3.2 如果不是接口,就创建一个ObjenesisCglibAopProxy,基于Cglib
3.3 先看下JdkDynamicAopProxy的invoke方法
3.3.1 如果方法是equals或者hashcode方法,并且目标对象未实现,就直接return
3.3.2 Advised接口或者其父接口中定义的方法,直接反射调用,不应用通知
3.3.3 获得目标对象的类,调用targetSource.getTarget();
3.3.4 获取可以应用到此方法上的拦截器Interceptor列表
3.3.5 如果拦截器Interceptor列表为空,就直接反射调用 AopUtils.invokeJoinpointUsingReflection。获取结果retVal
3.3.6 如果拦截器链不为空,那么便创建ReflectiveMethodInvocation类,把拦截器方法都封装在里面,也就是执行
3.3.7 继续看proceed()方法,
3.3.8 如果Interceptor执行完了,则执行joinPoint
3.3.9 如果要动态匹配joinPoint,需要检查运行时参数是否满足匹配条件。匹配成功,就执行当前的Interceptor
调用 return dm.interceptor.invoke(this);
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
四、生成代理的内部实现,调用proxy.newProxyInstance
调用代理对象的构造方法,生成代理类的实例
4.1 深入生成proxy class的细节,遍历目标类所实现的接口,获取目标类实现接口的名称列表
4.2 通过Class.forName(),加载目标类实现的接口到内存,也就是interfaceClass
4.3
4.4 生成代理类的字节码,细节如下
4.5 遍历每一个接口的每一个方法,生成对应的proxyMethod对象
4.6 组装要生成class文件的所有字段信息和方法信息
4.7 写入最终的class文件,如下
执行事务增强器
当判断某个bean适用于事务增强时,也就是用于增强器BeanFactoryTransactionAttributeSourceAdvisor这个类,所以在自定义标签解析时,注入的类成为了整个事务功能的基础。
BeanFactoryTransactionAttributeSourceAdvisor作为Advisor的实现类,需要遵从Advisor的处理方式,当代理被调用时会调用这个类的增强方法,也就是此bean的Advise,又因为在事务标签解析时我们把TransactionInterceptor类型的bean注入到了BeanFactoryTransactionAttributeSourceAdvisor中,所以在调用事务增强器增强的代理类时会先执行TransactionInterceptor进行增强,也就是执行TransactionInterceptor中的invoke方法完成整个事务的逻辑。
从时序图中可以看出:
- 解析注解事务中的属性;
- 根据属性设置创建事务;
- 在当前线程中执行用户真正的代码;
- 如果执行过程中有异常则执行回滚逻辑;
- 如果没有异常,则提交事务。 在前面讲解事务时说到过,spring事务是基于数据库本身的事务的,从时序图中也可以看出,创建事务,回滚事务,提交事务,操作都需要去操作数据库连接类DataSourceTransactionManager。
创建事务
看着时序图已经可以往下走了,下面将展示源码中个人觉得重要的点,其他不重要的由于篇幅问题就不帖出来了。
第一步:整个事务执行框架
TransactionInterceptor中的invoke执行了TransactionAspectSupport的invokeWithinTransaction方法。
第二步:获取事务注解属性
就是解析方法上面的:@Transactional(propagation = Propagation.REQUIRES_NEW)这个里面的属性设置。
第三步:根据上面获取的属性,创建事务
TransactionAspectSupport.createTransactionIfNecessary