找回密码
 立即注册
首页 业界区 业界 Spring IOC 源码学习 事务相关的 BeanDefinition 解析过 ...

Spring IOC 源码学习 事务相关的 BeanDefinition 解析过程 (XML)

东门芳洲 昨天 21:00
事务相关的 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. 解析

相关推荐

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

0

粉丝关注

27

主题发布

板块介绍填写区域,请于后台编辑