Spring事物的配置样式如下:
PROPAGATION_REQUIRED PROPAGATION_REQUIRED PROPAGATION_REQUIRED,readOnly
可以看出TransactionProxyFactoryBean是Spring事物的入口;在TransactionProxyFactoryBean中声明了
private final TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
并将TransactionManager, TransactionAttributes赋值给了transactionInterceptor拦截器。该类继承了AbstractSingletonProxyFactoryBean,而AbstractSingletonProxyFactoryBean又实现了InitializingBean接口;在bean初始化完成后会调用 AbstractSigletonProxyFactoryBean的afterPropertiesSet方法。在该方法中又调用了TransactionInterceptor的createMainInterceptor方法
// Add the main interceptor (typically an Advisor).
proxyFactory.addAdvisor(this.advisorAdapterRegistry.wrap(createMainInterceptor()));
protected Object createMainInterceptor() { this.transactionInterceptor.afterPropertiesSet(); if (this.pointcut != null) { return new DefaultPointcutAdvisor(this.pointcut, this.transactionInterceptor); } else { // Rely on default pointcut. return new TransactionAttributeSourceAdvisor(this.transactionInterceptor); } }
至此就完成了Spring事物通知器的注入。
后续的处理就和普通的AOP一样,我们都知道在Spring AOP中是通过JDK的动态代理和CGLIB实现的
JdkDynamicAopProxy.invoke 方法是AOP方法调用的入口。在该方法中有:
List
如果当前方法需要在事物中运行,在中会调用到TransactionInterceptor.invoke()方法。
public Object invoke(final MethodInvocation invocation) throws Throwable { // Work out the target class: may be {@code null}. // The TransactionAttributeSource should be passed the target class // as well as the method, which may be from an interface. Class> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null); // Adapt to TransactionAspectSupport's invokeWithinTransaction... return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() { public Object proceedWithInvocation() throws Throwable { return invocation.proceed(); } }); }
调用父类中的方法是先了事物处理
protected Object invokeWithinTransaction(Method method, Class targetClass, final InvocationCallback invocation) throws Throwable { // If the transaction attribute is null, the method is non-transactional. final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass); final PlatformTransactionManager tm = determineTransactionManager(txAttr); final String joinpointIdentification = methodIdentification(method, targetClass); 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); throw ex; } finally { cleanupTransactionInfo(txInfo); } commitTransactionAfterReturning(txInfo); return retVal; } else { // It's a CallbackPreferringPlatformTransactionManager: pass a TransactionCallback in. try { Object result = ((CallbackPreferringPlatformTransactionManager) tm).execute(txAttr, new TransactionCallback