上一节演示了基于tx标签和基于@Transactional注解的声明式事物的使用过程,本节分析一下基于@Transactional注解的声明式事物的实现过程。
1.快速定位Spring自定义标签解析入口
在上节的配置文件中,通过<tx:annotation-driven transaction-manager="transactionManager"/>
开启了注解事物,以此为入口,开始今天的分析。
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,然后解析<tx:annotation-driven/>
的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); // 解析<tx:annotation-driven>的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属性中。
当然分析到这里的时候,大家有可能会非常迷茫,不过没关系,我们在后面的章节会详细分析。