Spring事务注解实现的原理

Spring事务注解是个典型的Spring AOP的注解。方法上面加上@Transactional,方法就有了事务的能力。

面试中:基于动态代理讲更多的东西。。。。

为什么呢?--->其实里面核心也是动态代理。

在一个使用了ProfitDetailService对象方法上面加入了@Transactional注解,正常来说我们导入的应该是ProfitDetailServiceImp对象,但是debug出来的缺失$Proxy22。太熟悉了,肯定想到代理模式里面的动态代理。准备跳坑,进入

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {}。
JdkDynamicAopProxy为整个srpingAop的核心。JdkDynamicAopProxy 实现了InvocationHandler(业务上的增强器),初步猜测肯定要实现invoke()方法。调试之后,进入JdkDynamicAopProxy.java确实找到了invoke()。所有的springAOP都要经历invoke()。

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

  ............................

  //相关检验先不关心

// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

   ..........................

}

chain牛逼的东西来了,终于看到什么鬼责任链模式的玩意、了。对于Spring来讲,很多地方都要增强,所有但凡是AOP的增强都会进入到这个方法,加载一系列的拦截器。例如:方法上面加了@Transactional就会被TransactionInterceptor事务拦截器拦截;方法上如果加CashAble就会被CacheInterceptor拦截;异步注解对应异步拦截器等等这些拦截器都加载在责任链里面。

拦截器里面都会重写invoke()方法,思考事务拦截器这里是怎么增强的?

  1. 方法开启之前开启事务
  2. 如果方法出现异常,加个try catch 让事务回滚。
  3. 方法执行结束之后关闭事务

带着预想接着看下TransactionInterceptor里面重写的invoke()方法。

@Override
public Object invoke(final MethodInvocation invocation) throws Throwable {
   Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);

   // Adapt to TransactionAspectSupport's invokeWithinTransaction...
   return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
      @Override
      public Object proceedWithInvocation() throws Throwable {
         return invocation.proceed();
      }
   });
}

进入invokeWithinTransaction看源码:

protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
      throws Throwable {

   // If the transaction attribute is null, the method is non-transactional.
   // 解析Transaction注解上的相关属性(隔离级别、传播属性)
   final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
    // 解析完之后拿事务管理器
   final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    //获取方法上面的一些连接点
   final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);

   if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
      // Standard transaction demarcation with getTransaction and commit/rollback calls.

      //开启事务,并把自动提交关闭
      TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
      Object retVal = null;
      try {
         // This is an around advice: Invoke the next interceptor in the chain.
         // This will normally result in a target object being invoked.
         retVal = invocation.proceedWithInvocation();   //执行方法本身进行数据库操作
      }
      catch (Throwable ex) {
         // target invocation exception
         completeTransactionAfterThrowing(txInfo, ex);    //如果出现异常之后要回归 Rollback之后源码会展出。
         throw ex;
      }
      finally {
         cleanupTransactionInfo(txInfo);
      }
      commitTransactionAfterReturning(txInfo);   //没有异常提交事务
      return retVal;
   }

基本跟我们预期一致。这就是整个spring AOP进行增强的过程。

发布了68 篇原创文章 · 获赞 9 · 访问量 7450

猜你喜欢

转载自blog.csdn.net/u013025649/article/details/103459040