找回密码
 立即注册
首页 业界区 业界 一文学习 Spring 声明式事务源码全流程总结 ...

一文学习 Spring 声明式事务源码全流程总结

米嘉怡 昨天 23:15
Spring 声明式事务源码学习全过程

in short 四步走

  • Srping 如何从配置中加载的入口
  • Spring 声明式事务的相关的 BeanDefinition加载流程
  • Spring 声明式事务的相关对象创建流程
  • Spring 声明式事务的拦截调用的过程(包括: 方法嵌套, 事务传播属性的处理过程)
最后再看看第三方的框架是如何支持 Spring 声明式事务, 给Spring 托管事务的
一、Spring 声明式事务的入口点

对于XML入口点

XML配置定义
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3.            xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4.            xmlns:aop="http://www.springframework.org/schema/aop"
  5.            xmlns:tx="http://www.springframework.org/schema/tx"
  6.            xsi:schemaLocation="
  7.                 http://www.springframework.org/schema/beans
  8.                 https://www.springframework.org/schema/beans/spring-beans.xsd
  9.                 http://www.springframework.org/schema/tx
  10.                 https://www.springframework.org/schema/tx/spring-tx.xsd
  11.                 http://www.springframework.org/schema/aop
  12.                 https://www.springframework.org/schema/aop/spring-aop.xsd">
  13.         <tx:annotation-driven></tx:annotation-driven>
  14.        
  15.         <bean id="jdbcTemplate"  >
  16.                 <property name="dataSource" ref = "dataSource"></property>
  17.         </bean>
  18.        
  19.         <bean id="bookService"  >
  20.                 <property name="jdbcTemplate" ref="jdbcTemplate"></property>
  21.         </bean>
  22.        
  23.         <bean id="dataSource"  >
  24.                 <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"></property>
  25.                 <property name="url"
  26.        
  27.        
  28.        
  29.        
  30. </aop:config>  value="jdbc:mysql://192.168.40.171:3306/workflow_test?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false"/>
  31.                 <property name="username" value="user_dev"></property>
  32.                 <property name="password" value="dev-sny.com"></property>
  33.         </bean>
  34.        
  35.         <bean id="transactionManager"  >
  36.                 <constructor-arg ref="dataSource"></constructor-arg>
  37.         </bean>
  38.        
  39.                
  40.                
  41.                
  42.                
  43.         </aop:config>
  44.         <tx:advice id="txAdvice" transaction-manager="transactionManager">
  45.                 <tx:attributes>
  46.                         <tx:method name="get*" read-only="true"/>
  47.                         <tx:method name="insertWithTransaction" propagation="REQUIRED" />
  48.                         <tx:method name="insertWithNoTransaction" propagation="NEVER" />
  49.                 </tx:attributes>
  50.         </tx:advice>
  51. </beans>
复制代码
在XML中配置 tx:.. 启用tx标签, 在解析XML自定义标签时, 会拿到 TxNamespaceHandler 命名空间处理器, 其主要工作就是注册事务相关的标签的解析器

  • tx:advice 标签解析器:负责XML相关的标签解析 TxAdviceBeanDefinitionParser
  • tx:annotation-driven 标签解析器:负责注解相关的解析 AnnotationDrivenBeanDefinitionPar
org.springframework.transaction.config.TxNamespaceHandler
  1. public class TxNamespaceHandler extends NamespaceHandlerSupport {
  2.         static final String TRANSACTION_MANAGER_ATTRIBUTE = "transaction-manager";
  3.         static final String DEFAULT_TRANSACTION_MANAGER_BEAN_NAME = "transactionManager";
  4.         static String getTransactionManagerName(Element element) {
  5.                 return (element.hasAttribute(TRANSACTION_MANAGER_ATTRIBUTE) ?
  6.        
  7.        
  8.        
  9.        
  10. </aop:config>element.getAttribute(TRANSACTION_MANAGER_ATTRIBUTE) : DEFAULT_TRANSACTION_MANAGER_BEAN_NAME);
  11.         }
  12.         @Override
  13.         public void init() {
  14.                 //  <tx:advice> 标签解析器:负责解析XML <tx:advice> 事务标签配置 TxAdviceBeanDefinitionParser
  15.                 registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
  16.                 //  <tx:annotation-driven> 标签解析器:负责解析注解相关的事务配置 AnnotationDrivenBeanDefinitionParser
  17.                 registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
  18.                 // JTA 规范的分布式事务管理器(管理跨多个资源的事务) TODO
  19.                 registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
  20.         }
  21. }
复制代码
启用事务注解支持
  1. class AnnotationDrivenBeanDefinitionParser implements BeanDefinitionParser {
  2.         /**
  3.          * Parses the {@code <tx:annotation-driven/>} tag. Will
  4.          * {@link AopNamespaceUtils#registerAutoProxyCreatorIfNecessary register an AutoProxyCreator}
  5.          * with the container as necessary.
  6.          */
  7.         @Override
  8.         @Nullable
  9.         public BeanDefinition parse(Element element, ParserContext parserContext) {
  10.                 registerTransactionalEventListenerFactory(parserContext);
  11.                 String mode = element.getAttribute("mode");
  12.                 if ("aspectj".equals(mode)) {
  13.                         // mode="aspectj"
  14.                         registerTransactionAspect(element, parserContext);
  15.                         if (ClassUtils.isPresent("jakarta.transaction.Transactional", getClass().getClassLoader())) {
  16.        
  17.        
  18.        
  19.        
  20. </aop:config>registerJtaTransactionAspect(element, parserContext);
  21.                         }
  22.                 }
  23.                 else {
  24.                         // 默认是  proxy 模式
  25.                         // mode="proxy"
  26.                         AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext);
  27.                 }
  28.                 return null;
  29.         }
  30.        
复制代码
注册三剑客
  1. /**
  2. * Inner class to just introduce an AOP framework dependency when actually in proxy mode.
  3. */
  4. private static class AopAutoProxyConfigurer {
  5.         public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
  6.                 AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
  7.                 String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
  8.                 if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
  9.                         Object eleSource = parserContext.extractSource(element);
  10.                         // Create the TransactionAttributeSource definition.
  11.                         RootBeanDefinition sourceDef = new RootBeanDefinition(
  12.        
  13.        
  14.        
  15.        
  16. </aop:config>        "org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
  17.                         sourceDef.setSource(eleSource);
  18.                         sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
  19.                         String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);
  20.                         // Create the TransactionInterceptor definition.
  21.                         RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
  22.                         interceptorDef.setSource(eleSource);
  23.                         interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
  24.                         registerTransactionManager(element, interceptorDef);
  25.                         interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
  26.                         String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);
  27.                         /**
  28.                          * 其中构建事务增强器(BeanFactoryTransactionAttributeSourceAdvisor)
  29.                          * - **Pointcut(切点)**: 默认匹配所有标注 `@Transactional` 的类 / 方法(由 `TransactionAttributeSourcePointcut` 实现)
  30.                          * - **Advice(通知)**: 即 `TransactionInterceptor`(事务拦截器)
  31.                          * - **TransactionAttributeSource(注解解析器)**:即 `AnnotationTransactionAttributeSource`, 负责解析 `@Transactional` 注解的属性(传播行为、隔离级别等)。
  32.                          */
  33.                         // Create the TransactionAttributeSourceAdvisor definition.
  34.                         RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
  35.                         advisorDef.setSource(eleSource);
  36.                         advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
  37.                         advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
  38.                         advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
  39.                         if (element.hasAttribute("order")) {
  40.        
  41.        
  42.        
  43.        
  44. </aop:config>advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
  45.                         }
  46.                         parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);
  47.                         CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
  48.                         compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
  49.                         compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
  50.                         compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
  51.                         parserContext.registerComponent(compositeDef);
  52.                 }
  53.         }
  54. }
复制代码
事务注解支持的三剑客


  • AnnotationTransactionAttributeSource
    ↓(解析注解)
  • TransactionInterceptor
    ↓(执行事务逻辑)
  • BeanFactoryTransactionAttributeSourceAdvisor
    ↓(组装切点+通知)
总结一下XML入口, 就是无论 xml 支持 还是注解支持都会构造 org.springframework.transaction.interceptor.TransactionInterceptor 这个核心 advice 事务拦截器
对于注解的入口
  1. @EnableTransactionManagement
  2. public class TXMain {
  3.         @Transactional
  4.         public static void main(String[] args) throws Exception {
  5.                 System.out.println("==========================================================");
  6.                 //ApplicationContext context = new ClassPathXmlApplicationContext("application-tx.xml");
  7.                 AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TXMain.class);
  8.                 BookService bookService = context.getBean("bookService", BookService.class);
  9.                 Book book = new Book();
  10.                 book.setName("30秒精通javascript,一分钟精通java");
  11.                 book.setCode(""+System.currentTimeMillis());
  12. //                bookService.insertWithTransaction(book );
  13.                 bookService.insertWithNoTransaction(book);
  14.                 System.out.println("bookService = "+bookService);
  15.                 System.out.println("bookService getList = "+bookService.getList());
  16.                 System.out.println("==========================================================");
  17.         }
  18. }
复制代码
@EnableTransactionManagement 注解导入了 TransactionManagementConfigurationSelector 默认选中的是 ProxyTransactionManagementConfiguration
  1. public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
  2.         /**
  3.          * Returns {@link ProxyTransactionManagementConfiguration} or
  4.          * {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
  5.          * and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
  6.          * respectively.
  7.          */
  8.         @Override
  9.         protected String[] selectImports(AdviceMode adviceMode) {
  10.                 return switch (adviceMode) {
  11.                
  12.                         case PROXY -> new String[] {AutoProxyRegistrar.class.getName(),
  13.        
  14.        
  15.        
  16.        
  17. </aop:config>        ProxyTransactionManagementConfiguration.class.getName()};
  18.                         case ASPECTJ -> new String[] {determineTransactionAspectClass()};
  19.                 };
  20.         }
  21.         private String determineTransactionAspectClass() {
  22.                 return (ClassUtils.isPresent("jakarta.transaction.Transactional", getClass().getClassLoader()) ?
  23.        
  24.        
  25.        
  26.        
  27. </aop:config>TransactionManagementConfigUtils.JTA_TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME :
  28.        
  29.        
  30.        
  31.        
  32. </aop:config>TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME);
  33.         }
  34. }
复制代码
同样注解的三剑客


  • AnnotationTransactionAttributeSource
    ↓(解析注解)
  • TransactionInterceptor
    ↓(执行事务逻辑)
  • BeanFactoryTransactionAttributeSourceAdvisor
    ↓(组装切点+通知)
org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration
  1. /*
  2. * Copyright 2002-2021 the original author or authors.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. *      https://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.springframework.transaction.annotation;
  17. import org.springframework.beans.factory.config.BeanDefinition;
  18. import org.springframework.context.annotation.Bean;
  19. import org.springframework.context.annotation.Configuration;
  20. import org.springframework.context.annotation.ImportRuntimeHints;
  21. import org.springframework.context.annotation.Role;
  22. import org.springframework.transaction.config.TransactionManagementConfigUtils;
  23. import org.springframework.transaction.interceptor.BeanFactoryTransactionAttributeSourceAdvisor;
  24. import org.springframework.transaction.interceptor.TransactionAttributeSource;
  25. import org.springframework.transaction.interceptor.TransactionInterceptor;
  26. /**
  27. * {@code @Configuration} class that registers the Spring infrastructure beans
  28. * necessary to enable proxy-based annotation-driven transaction management.
  29. *
  30. * @author Chris Beams
  31. * @author Sebastien Deleuze
  32. * @since 3.1
  33. * @see EnableTransactionManagement
  34. * @see TransactionManagementConfigurationSelector
  35. */
  36. @Configuration(proxyBeanMethods = false)
  37. @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  38. @ImportRuntimeHints(TransactionRuntimeHints.class)
  39. public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
  40.         @Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
  41.         @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  42.         public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
  43.                         TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
  44.                 BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
  45.                 advisor.setTransactionAttributeSource(transactionAttributeSource);
  46.                 advisor.setAdvice(transactionInterceptor);
  47.                 if (this.enableTx != null) {
  48.                         advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
  49.                 }
  50.                 return advisor;
  51.         }
  52.         @Bean
  53.         @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  54.         public TransactionAttributeSource transactionAttributeSource() {
  55.                 // Accept protected @Transactional methods on CGLIB proxies, as of 6.0.
  56.                 return new AnnotationTransactionAttributeSource(false);
  57.         }
  58.         @Bean
  59.         @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
  60.         public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
  61.                 TransactionInterceptor interceptor = new TransactionInterceptor();
  62.                 interceptor.setTransactionAttributeSource(transactionAttributeSource);
  63.                 if (this.txManager != null) {
  64.                         interceptor.setTransactionManager(this.txManager);
  65.                 }
  66.                 return interceptor;
  67.         }
  68. }
复制代码
总结流程图

1.png

二、事务相关的 BeanDefinition 解析过程 (XML)

bean 标签

对于 jdbcTemplate transactionManager dataSource bookService 走的是默认命名空间的处理器, IOC标准解析流程, 不再啰嗦了
[[Spring IOC 源码学习 XML详细加载流程总结]]
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
  1. protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
  2.         if (delegate.isDefaultNamespace(root)) {
  3.                 NodeList nl = root.getChildNodes();
  4.                 for (int i = 0; i < nl.getLength(); i++) {
  5.                         Node node = nl.item(i);
  6.                         if (node instanceof Element ele) {//是否 是元素标签
  7.        
  8.        
  9.        
  10.        
  11. </aop:config>/**
  12.        
  13.        
  14.        
  15.        
  16. </aop:config> * 处理默认命名空间的标签, 有如下四个
  17.        
  18.        
  19.        
  20.        
  21. </aop:config> * <import></import>,  </alias>, <bean></bean>, <beans></beans>
  22.        
  23.        
  24.        
  25.        
  26. </aop:config> *
  27.        
  28.        
  29.        
  30.        
  31. </aop:config> */
  32.        
  33.        
  34.        
  35.        
  36. </aop:config>if (delegate.isDefaultNamespace(ele)) {
  37.        
  38.        
  39.        
  40.        
  41. </aop:config>        parseDefaultElement(ele, delegate);
  42.        
  43.        
  44.        
  45.        
  46. </aop:config>}
  47.        
  48.        
  49.        
  50.        
  51. </aop:config>else {
  52.        
  53.        
  54.        
  55.        
  56. </aop:config>        /**
  57.        
  58.        
  59.        
  60.        
  61. </aop:config>         * 处理 非默认命名空间的标签;
  62.        
  63.        
  64.        
  65.        
  66. </aop:config>         *         注意这里包括 <context:bean ...>  <tx:xx ...> 等等所有指定命名空间的xml配置
  67.        
  68.        
  69.        
  70.        
  71. </aop:config>         *         主要逻辑是: 拿到元素的命名空间URI, 再从 XmlReaderContext 找到对应的 NamespaceHandler 调用解析 `parse`方法解析到 BeanDefinition 返回
  72.        
  73.        
  74.        
  75.        
  76. </aop:config>         */
  77.        
  78.        
  79.        
  80.        
  81. </aop:config>        delegate.parseCustomElement(ele);
  82.        
  83.        
  84.        
  85.        
  86. </aop:config>}
  87.                         }
  88.                 }
  89.         }
  90.         else {
  91.                 delegate.parseCustomElement(root);
  92.         }
  93. }
复制代码
aop 标签

对于 aop 部分的标签则的是 AOP 的流程
  1.        
  2.        
  3.        
  4.        
  5. </aop:config>
复制代码

  • : 解析为 org.springframework.aop.aspectj.AspectJExpressionPointcut 其 BeanDefinition
  • :  解析为 org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor 其 BeanDefinition
internalAutoProxyCreator 的注册

[[Spring AOP 源码学习 详细流程总结]]
这里要注意AOP 的 ConfigBeanDefinitionParser 在解析时是会注册的一个internalAutoProxyCreator! (AOP解析流程, 在BPP回调时创建代理对象的)
org.springframework.aop.config.ConfigBeanDefinitionParser#parse
  1.         @Override        @Nullable        public BeanDefinition parse(Element element, ParserContext parserContext) {                CompositeComponentDefinition compositeDef =       
  2.        
  3.        
  4.        
  5. </aop:config>new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));                parserContext.pushContainingComponent(compositeDef);                /**                 * 1. 注册一个名称为`org.springframework.aop.config.internalAutoProxyCreator` 对AOP处理的Bean Definition; 它是实现 InstantiationAwareBeanPostProcessor 接口的                 * 名称是: org.springframework.aop.config.internalAutoProxyCreator                 * 对应的类, 根据情况有以下三个可能: org.springframework.aop.config.AopConfigUtils#APC_PRIORITY_LIST                 *            InfrastructureAdvisorAutoProxyCreator.class,AspectJAwareAdvisorAutoProxyCreator.class, AnnotationAwareAspectJAutoProxyCreator.class                 *         注册一个名称为`org.springframework.aop.config.internalAutoProxyCreator` 对AOP处理的Bean Definition; 它是实现 InstantiationAwareBeanPostProcessor 接口的                 *                 */                configureAutoProxyCreator(parserContext, element);
复制代码
解析 , , 没有切面标签
org.springframework.aop.config.ConfigBeanDefinitionParser#parse
  1.         @Override        @Nullable        public BeanDefinition parse(Element element, ParserContext parserContext) {                CompositeComponentDefinition compositeDef =       
  2.        
  3.        
  4.        
  5. </aop:config>new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));                parserContext.pushContainingComponent(compositeDef);                /**                 * 1. 注册一个名称为`org.springframework.aop.config.internalAutoProxyCreator` 对AOP处理的Bean Definition; 它是实现 InstantiationAwareBeanPostProcessor 接口的                 * 名称是: org.springframework.aop.config.internalAutoProxyCreator                 * 对应的类, 根据情况有以下三个可能: org.springframework.aop.config.AopConfigUtils#APC_PRIORITY_LIST                 *            InfrastructureAdvisorAutoProxyCreator.class,AspectJAwareAdvisorAutoProxyCreator.class, AnnotationAwareAspectJAutoProxyCreator.class                 *         注册一个名称为`org.springframework.aop.config.internalAutoProxyCreator` 对AOP处理的Bean Definition; 它是实现 InstantiationAwareBeanPostProcessor 接口的                 *                 */                configureAutoProxyCreator(parserContext, element);                /**                 * 2. 解析  标签的子元素 (pointcut, advisor, aspect)                 * 解析 :                 * 每一个通知(Advice) 都会封装为一个 AspectJPointcutAdvisor 的BeanDefinition 然后将其注册到 BeanFactory                 *                 *  AspectJPointcutAdvisor 的包含情况                 * 每一个通知(Advice) 都会封装为一个 AspectJPointcutAdvisor(通知器) 类型的BeanDefinition 然后将其注册到 BeanFactory                 *         AspectJPointcutAdvisor 内部包含五种通知类类型:  AspectJAfterReturningAdvice AspectJAfterAdvice AspectJAroundAdvice AspectJMethodBeforeAdvice AspectJAfterThrowingAdvice                 *  而每种通知类型的内部又主要有三个关键属性,包括:                 *  1. java.lang.reflect.Method(通知切面的方法)                 *        2. org.springframework.aop.aspectj.AspectJExpressionPointcut(切入点表达式)                 *         3. org.springframework.aop.aspectj.AspectInstanceFactory (切面实例工厂)                 */                List childElts = DomUtils.getChildElements(element);                for (Element elt: childElts) {                        String localName = parserContext.getDelegate().getLocalName(elt);                        switch (localName) {       
  6.        
  7.        
  8.        
  9. </aop:config>/**       
  10.        
  11.        
  12.        
  13. </aop:config> * 解析 pointcut/切入点  //筛选连接点, 即: 哪些方法需要被代理       
  14.        
  15.        
  16.        
  17. </aop:config> * 解析为 org.springframework.aop.aspectj.AspectJExpressionPointcut 注册其 BeanDefinition       
  18.        
  19.        
  20.        
  21. </aop:config> */       
  22.        
  23.        
  24.        
  25. </aop:config>case POINTCUT -> parsePointcut(elt, parserContext);       
  26.        
  27.        
  28.        
  29. </aop:config>/**       
  30.        
  31.        
  32.        
  33. </aop:config> *  解析 advisor/通知/建议/增强处理  //即: 增强功能这一部分代码       
  34.        
  35.        
  36.        
  37. </aop:config> * 解析为 org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor 注册其 BeanDefinition       
  38.        
  39.        
  40.        
  41. </aop:config> */       
  42.        
  43.        
  44.        
  45. </aop:config>case ADVISOR -> parseAdvisor(elt, parserContext);       
  46.        
  47.        
  48.        
  49. </aop:config>/**       
  50.        
  51.        
  52.        
  53. </aop:config>       
  54.        
  55.        
  56.        
  57. </aop:config> */       
  58.        
  59.        
  60.        
  61. </aop:config>case ASPECT -> parseAspect(elt, parserContext);                        }                }                parserContext.popAndRegisterContainingComponent();                return null;        }
复制代码
tx 标签

前文说了由 org.springframework.transaction.config.TxAdviceBeanDefinitionParser 负责XML解析
先来到父类方法解析 TransactionInterceptor

org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser#parseInternal
[code]/**         * Creates a {@link BeanDefinitionBuilder} instance for the         * {@link #getBeanClass bean Class} and passes it to the         * {@link #doParse} strategy method.         * @param element the element that is to be parsed into a single BeanDefinition         * @param parserContext the object encapsulating the current state of the parsing process         * @return the BeanDefinition resulting from the parsing of the supplied {@link Element}         * @throws IllegalStateException if the bean {@link Class} returned from         * {@link #getBeanClass(org.w3c.dom.Element)} is {@code null}         * @see #doParse         *         */        @Override        protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {                /**                 *                 * 1. 解析

相关推荐

您需要登录后才可以回帖 登录 | 立即注册