东门芳洲 发表于 昨天 21:00

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

事务相关的 BeanDefinition 解析过程 (XML)
bean 标签

对于 jdbcTemplate transactionManager dataSource bookService 走的是默认命名空间的处理器, IOC标准解析流程, 不再啰嗦了
[]
org.springframework.beans.factory.xml.DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
        if (delegate.isDefaultNamespace(root)) {
                NodeList nl = root.getChildNodes();
                for (int i = 0; i < nl.getLength(); i++) {
                        Node node = nl.item(i);
                        if (node instanceof Element ele) {//是否 是元素标签
       
       
       
       
</aop:config>/**
       
       
       
       
</aop:config> * 处理默认命名空间的标签, 有如下四个
       
       
       
       
</aop:config> * <import></import>,</alias>, <bean></bean>, <beans></beans>
       
       
       
       
</aop:config> *
       
       
       
       
</aop:config> */
       
       
       
       
</aop:config>if (delegate.isDefaultNamespace(ele)) {
       
       
       
       
</aop:config>        parseDefaultElement(ele, delegate);
       
       
       
       
</aop:config>}
       
       
       
       
</aop:config>else {
       
       
       
       
</aop:config>        /**
       
       
       
       
</aop:config>       * 处理 非默认命名空间的标签;
       
       
       
       
</aop:config>       *         注意这里包括 <context:bean ...><tx:xx ...> 等等所有指定命名空间的xml配置
       
       
       
       
</aop:config>       *         主要逻辑是: 拿到元素的命名空间URI, 再从 XmlReaderContext 找到对应的 NamespaceHandler 调用解析 `parse`方法解析到 BeanDefinition 返回
       
       
       
       
</aop:config>       */
       
       
       
       
</aop:config>        delegate.parseCustomElement(ele);
       
       
       
       
</aop:config>}
                        }
                }
        }
        else {
                delegate.parseCustomElement(root);
        }
}aop 标签

对于 aop 部分的标签则的是 AOP 的流程
       
       
       
       
</aop:config>
[*] : 解析为 org.springframework.aop.aspectj.AspectJExpressionPointcut 其 BeanDefinition
[*]:解析为 org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor 其 BeanDefinition
internalAutoProxyCreator 的注册

[]
这里要注意AOP 的 ConfigBeanDefinitionParser 在解析时是会注册的一个internalAutoProxyCreator! (AOP解析流程, 在BPP回调时创建代理对象的)
org.springframework.aop.config.ConfigBeanDefinitionParser#parse
        @Override        @Nullable        public BeanDefinition parse(Element element, ParserContext parserContext) {                CompositeComponentDefinition compositeDef =       
       
       
       
</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
        @Override        @Nullable        public BeanDefinition parse(Element element, ParserContext parserContext) {                CompositeComponentDefinition compositeDef =       
       
       
       
</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) {       
       
       
       
</aop:config>/**       
       
       
       
</aop:config> * 解析 pointcut/切入点//筛选连接点, 即: 哪些方法需要被代理       
       
       
       
</aop:config> * 解析为 org.springframework.aop.aspectj.AspectJExpressionPointcut 注册其 BeanDefinition       
       
       
       
</aop:config> */       
       
       
       
</aop:config>case POINTCUT -> parsePointcut(elt, parserContext);       
       
       
       
</aop:config>/**       
       
       
       
</aop:config> *解析 advisor/通知/建议/增强处理//即: 增强功能这一部分代码       
       
       
       
</aop:config> * 解析为 org.springframework.aop.support.DefaultBeanFactoryPointcutAdvisor 注册其 BeanDefinition       
       
       
       
</aop:config> */       
       
       
       
</aop:config>case ADVISOR -> parseAdvisor(elt, parserContext);       
       
       
       
</aop:config>/**       
       
       
       
</aop:config>       
       
       
       
</aop:config> */       
       
       
       
</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
/**       * 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. 解析
页: [1]
查看完整版本: Spring IOC 源码学习 事务相关的 BeanDefinition 解析过程 (XML)