一、InfrastructureAdvisorAutoProxyCreator
1、它是通过@EnableTransactionManagement、< tx:annotation-driven /> 注入的,下面以@EnableTransactionManagement注解的方式为例,看下是如何注入的。
TransactionManagementConfigurationSelector#selectImports()
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {
TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
default:
return null;
}
}
默认进入PROXY分支,注入两个类:AutoProxyRegistrar、ProxyTransactionManagementConfiguration。AutoProxyRegistrar注入了InfrastructureAdvisorAutoProxyCreator,而ProxyTransactionManagementConfiguration则注入了AnnotationTransactionAttributeSource、TransactionInterceptor、BeanFactoryTransactionAttributeSourceAdvisor这三个类,他们支撑了整个事务的功能。
仔细回忆一下AOP的源码,BeanFactoryTransactionAttributeSourceAdvisor,TransactionInterceptor不就是AOP的增强器和拦截器链吗?只不过是Spring事务帮我们直接定义好了,不需要再创建而已,所以说AOP是Spring事务的基础!
回顾一下AOP的原理,AOP中有一个 Advisor 存放在代理类中,而Advisor中有advise与pointcut信息,每次执行被代理类的方法时都会执行代理类的invoke(如果是JDK代理)方法,而invoke方法会根据advisor中的pointcut动态匹配这个方法需要执行的advise链,遍历执行advise链,从而达到AOP切面编程的目的。
通过源码和类图可以直观的看到三者之间的关系:
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor() {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
// 将pointcut注入进advisor中
advisor.setTransactionAttributeSource(transactionAttributeSource());
// 将advice注入进advisor中
advisor.setAdvice(transactionInterceptor());
advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
return advisor;
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionAttributeSource transactionAttributeSource() {
return new AnnotationTransactionAttributeSource();
}
@Bean
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor() {
TransactionInterceptor interceptor = new TransactionInterceptor();
interceptor.setTransactionAttributeSource(transactionAttributeSource());
if (this.txManager != null) {
interceptor.setTransactionManager(this.txManager);
}
return interceptor;
}
}
2、看下它的继承关系:
3、由上图可知,InfrastructureAdvisorAutoProxyCreator分别继承了BeanPostProcessor、InstantiationAwareBeanPostProcessor,所以AnnotationAwareAspectJAutoProxyCreator会有postProcessAfterInitialization() 和 postProcessBeforeInstantiation() 方法,接下来的分析重点和AOP几乎一模一样的,可以参考《Spring源码阅读-AOP》 这篇文章的分析过程。
二、Spring事务的调用-TransactionInterceptor
1、TransactionInterceptor#invoke()方法是Spring事务最终调用的地方,看下源码:
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() {
@Override
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, 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 {
// spring事务是个环绕通知,在此执行目标方法
// 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;
}
*******
}
由上述代码和注释可知spring事务是个环绕通知!
2、另外如下调用链是Spring事务传播行为相关的代码,可以在此方法中进行查看分析。
TransactionAspectSupport#createTransactionIfNecessary
->AbstractPlatformTransactionManager#getTransaction