上一节演示了基于tx标签和基于@Transactional注解的声明式事物的使用过程,本节分析一下基于@Transactional注解的声明式事物的实现过程。
1.快速定位Spring自定义标签解析入口
在上节的配置文件中,通过
开启了注解事物,以此为入口,开始今天的分析。
tx是Spring的自定义标签,在32--aspectj-autoproxy解析及Spring解析自定义标签一节中已经分析过自定义标签的解析过程,Spring通过继承NamespaceHandler自定义命名空间的解析,以此推论,tx标签必然也有自己的命名空间解析器,通过全局搜索,可以找到TxNamespaceHandler类下包含了annotation-driven
。通过该方法如果大家再遇到Spring的自定义标签,可通过此方式为入口,快速找到分析入口所在。
2.
解析过程
按照我们之前章节的分析,注册了BeanDefinitionParser之后紧接着就要调用其parse方法对xml标签进行解析。(不清楚该过程的可以参考:32--aspectj-autoproxy解析及Spring解析自定义标签中的分析)。
public class TxNamespaceHandler extends NamespaceHandlerSupport {
static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";
static String getTransactionManagerName(Element element) {
return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
}
@Override
public void init() {
registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
// 注册AnnotationDrivenBeanDefinitionParser
registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
}
}
在TxNamespaceHandler中完成了对AnnotationDrivenBeanDefinitionParser的注册,接下来就要调用其parse方法。
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 1、注册TransactionalEventListenerFactory
registerTransactionalEventListenerFactory(parserContext);
// 2、解析标签的mode属性
String mode = element.getAttribute("mode");
if ("aspectj".equals(mode)) {
// mode="aspectj"
// aspectj模式
registerTransactionAspect(element, parserContext);
if (ClassUtils.isPresent("javax.transaction.Transactional", getClass().getClassLoader())) {
registerJtaTransactionAspect(element, parserContext);
}
}
else {
// mode="proxy"
// proxy模式
AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
}
return null;
}
在parse方法里,首先注册了TransactionalEventListenerFactory,然后解析
的mode属性,这里我们主要分析proxy模式。
/**
* 在代理模式下引入AOP框架依赖关系的内部类。
* Inner class to just introduce an AOP framework dependency when actually in proxy mode.
*/
private static class AopAutoProxyConfigurer {
public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
// 1、注册InfrastructureAdvisorAutoProxyCreator Infrastructure-->基础设施
// 注意:区分@AspectJ:@AspectJ注册的是AnnotationAwareAspectJAutoProxyCreator
AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
// TRANSACTION_ADVISOR_BEAN_NAME-->org.springframework.transaction.config.internalTransactionAdvisor
String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
Object eleSource = parserContext.extractSource(element);
// Create the TransactionAttributeSource definition.
// 2、创建AnnotationTransactionAttributeSource的BeanDefinition
RootBeanDefinition sourceDef = new RootBeanDefinition(
"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
sourceDef.setSource(eleSource);
// 设置Role属性,ROLE_INFRASTRUCTURE表示Spring的内部bean
sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 生成bean名称
String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
// Create the TransactionInterceptor definition.
// 3、创建TransactionInterceptor的BeanDefinition
RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
interceptorDef.setSource(eleSource);
// 设置Role属性,ROLE_INFRASTRUCTURE表示Spring的内部bean
interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 注册事物管理器
registerTransactionManager(element, interceptorDef);
// 将AnnotationTransactionAttributeSource注入到TransactionInterceptor的transactionAttributeSource属性中
interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
// 生成bean名称
String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
// Create the TransactionAttributeSourceAdvisor definition.
// 4、创建BeanFactoryTransactionAttributeSourceAdvisor的BeanDefinition
RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
advisorDef.setSource(eleSource);
// 设置Role属性,ROLE_INFRASTRUCTURE表示Spring的内部bean
advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
// 将上一步创建的AnnotationTransactionAttributeSource注入到
// BeanFactoryTransactionAttributeSourceAdvisor的transactionAttributeSource属性中
advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
// 将上一步创建的TransactionInterceptor注入到
// BeanFactoryTransactionAttributeSourceAdvisor的adviceBeanName属性中
advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
// 解析的order属性标签
if (element.hasAttribute("order")) {
advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
}
// 将TransactionAttributeSourceAdvisor以txAdvisorBeanName为名称注册到IOC容器中
parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
/**
* 通过上面的操作:
* 1、创建AnnotationTransactionAttributeSource的BeanDefinition
* 2、创建TransactionInterceptor的BeanDefinition
* 3、创建TransactionAttributeSourceAdvisor的BeanDefinition,
* 并将第一步,第二步创建的BeanDefinition注入到transactionAttributeSource和adviceBeanName中
*
* BeanFactoryTransactionAttributeSourceAdvisor-->TransactionInterceptor
* BeanFactoryTransactionAttributeSourceAdvisor-->AnnotationTransactionAttributeSource
*/
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
parserContext.registerComponent(compositeDef);
}
}
}
上面的这段代码,看起来枯燥无比,但这段代是Spring声明式事物的核心所在,下面对其中的细节逐一分析。
2.1注册InfrastructureAdvisorAutoProxyCreator
在之前的章节分析SpringAOP时,曾经注册了AnnotationAwareAspectJAutoProxyCreator,该类的作用是为目标对象自动创建代理,该类间接实现了BeanPostProcessor接口,所以会在bean的实例化前后调用postProcessBeforeInstantiation和postProcessAfterInitialization方法,这些在之前的章节中已经反复讲解过。
那么InfrastructureAdvisorAutoProxyCreator类是否有同样的作用呢?来查看一下其类继承关系不难发现其也间接实现了BeanPostProcessor接口,那么只要找到该类或者其父类中的postProcessBeforeInstantiation方法和postProcessAfterInitialization方法,就不难分析出其作用。这了也是一点点源码分析的小技巧,关于此类的作用,我们留在后面分析,接下来继续看configureAutoProxyCreator方法。
2.2 创建AnnotationTransactionAttributeSource的BeanDefinition
该过程比较简单,但是要分析一下AnnotationTransactionAttributeSource的作用。打开该类的代码,看起来毫无头绪,这时候不妨查看一下其类继承关系,或许就有新的发现,这也是阅读源码的小技巧。
可以看到该类实现了TransactionAttributeSource接口,该接口只提供了一个获取TransactionAttribute的方法
TransactionAttribute getTransactionAttribute(Method method, @Nullable Class> targetClass);
。TransactionAttribute实现了TransactionDefinition接口,该接口提供了Spring事物的传播特性以及事物隔离级别等定义。
综合上述分析,大致可以了解到AnnotationTransactionAttributeSource已经可以获取到事物属性,再通过该类是Annotation开头,也可以再次猜测该类是获取类、接口、方法上的事物注解属性。当然这里只是猜测,到底是不是呢?我们留在后面分析。
2.3 创建TransactionInterceptor的BeanDefinition
TransactionInterceptor是Spring声明式事物管理器的基础,查看其类图结构,TransactionInterceptor继承了TransactionAspectSupport并实现了MethodInterceptor接口。TransactionAspectSupport提供了对事物支持的能力,而MethodInterceptor我们之前已经介绍过,可以用来实现环绕增强。从此我们大致可以推断出,Spring的事物管理是基于环绕增强的。该类的具体方法以及调用过程留在后面分析。
2.4 创建TransactionAttributeSourceAdvisor的BeanDefinition并注册bean
上面已经创建了事物属性定义、事物增强定义、那么接下来就应该创建切面了。
从类图上看到BeanFactoryTransactionAttributeSourceAdvisor是PointcutAdvisor类型的切面,创建了该bean的定义之后,又将上面创建的AnnotationTransactionAttributeSource注入到transactionAttributeSource属性中;将TransactionInterceptor注入到adviceBeanName属性中。
当然分析到这里的时候,大家有可能会非常迷茫,不过没关系,我们在后面的章节会详细分析。