首先,如果在某个类或某个方法被标记为@Transactional时,Spring boot底层会在创建这个bean时生成代理对象(默认使用cglib)
示例:
当调用studentService的addStudent方法时,会直接跳到CglibAopProxy类去执行intercept方法(因为studentService是使用cglib生成的代理对象)
当执行
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
到这句时,chain里就是Spring Boot在生成代理对象时配置的Advisor,实际就是一个TransactionInterceptor.接着往下执行,到
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
将进入CglibAopProxy类,如下图proceed方法
它将调用父类ReflectiveMethodInvocation的proceed方法,
执行到最下边return那行时,会进入TransactionInterceptor的invoke方法,代码如下:
可以看到调用了invokeWithinTransaction方法,代码如下图所示
invocationTransaction代码如下:
其中createTransactionIfNecessary用来开启事务,commitTransactionAfterReturning用来提交事务,
retVal = invocation.proceedWithinTransaction用来执行业务代码,
执行invocation.proceedWithinTransaction会回到TransactionInterceptor类:
执行invocation.proceed,回到CgligApoProxy类:
调用super.proceed回到父类ReflectiveInvocationMethodInvocation,
如上图,这次将执行invokeJoinpoint方法,也就是我们自己定义的业务方法,invokeJoinpoint代码如下:
从上图可以看到,通过反射的方式调用了我们自己定义的业务方法,然后返回到ReflectiveMethodInvocation类:
继续返回到CglibAopProxy类:
继续返回TransactionInterceptor类的invoke方法:
继续返回,
retVal拿到了业务方法调用的结果,然后调用commitTransactionAfterReturning,将事务提交,整个流程结束