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进行增强的过程。
来源:CSDN
作者:骑机车的程序猿
链接:https://blog.csdn.net/u013025649/article/details/103459040