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()方法,思考事务拦截器这里是怎么增强的?
- 方法开启之前开启事务
- 如果方法出现异常,加个try catch 让事务回滚。
- 方法执行结束之后关闭事务
带着预想接着看下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进行增强的过程。