美文网首页
003-bean xml 解析流程

003-bean xml 解析流程

作者: 当当一丢丢 | 来源:发表于2020-03-15 17:26 被阅读0次

    一.需求

    探讨Spring 配置文件 bean.xml 中元素是如何被解析的

    二.xml构成划分

    1.dispatcher-servlet.xml案例

    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:aop="http://www.springframework.org/schema/aop"
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:tx="http://www.springframework.org/schema/tx" 
        xmlns:util="http://www.springframework.org/schema/util"
    
        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  
            http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd  
            http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd  
            http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.1.xsd">
    
        <context:component-scan base-package="com.beijing"
        <bean id="student" class="com.beijing.Student">
    
    </beans>
    

    2.dispatcher-servlet.xml构成

    2.1schema

    schema即beans 标签属性, 大致分为两部分 xmlns, xsi:schemaLocation

    • xml namespace,xmlns作用有二
      • 定义与下文xsi:schemaLoaction的关联关系,整体结构:
        xmlns:mvc="key"
        xsi:schemaLocation="key keyLocation"
      • 定义下文标签的使用方式,整体结构:
        xmlns:context="key"
        <context: component-scan="">
        xmlns:context="http://www.springframework.org/schema/context"
        xmlns:jpa="http://www.springframework.org/schema/data/jpa" 
        xmlns:mvc="http://www.springframework.org/schema/mvc"
        xmlns:tx="http://www.springframework.org/schema/tx"
    
    • xsi:schemalocation
      • schemaLocation定义了namespace下面可用的属性,属性格式等信息
      • namespace的schema可以有不同版本,比如spring-beans-3.1.xsd ,spring-beans-4.1.xsd
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd  
            http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd  
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd  
    

    2.2namespace

    • namespace是上文提到的context,即xmlns:context中的context,其他同理

    2.3element

    • element为<context:component-scan="">中的component-scan
    • 可以做如此类比:namespace为MySQL中的DB,元素为table,element为table中的field
    • 那namespace可以使用哪些element呢(只需判断table中定义了哪些field),这就是上面的schemaLocation的作用了,如下是schemaLocation value =http://www.springframework.org/schema/context/spring-context-4.1.xsd的大致内容
      • 可以看到context下可以定义annotation-config,component-scan等元素
      • 可以看成其中component-scan中定义了可以使用的field,如base-package,及其use为required不可或缺
    <xsd:schema xmlns="http://www.springframework.org/schema/context" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:beans="http://www.springframework.org/schema/beans" xmlns:tool="http://www.springframework.org/schema/tool" targetNamespace="http://www.springframework.org/schema/context" elementFormDefault="qualified" attributeFormDefault="unqualified">
    <xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="https://www.springframework.org/schema/beans/spring-beans-4.1.xsd"/>
    <xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="https://www.springframework.org/schema/tool/spring-tool-4.1.xsd"/>
        <xsd:annotation>...</xsd:annotation>
        <xsd:complexType name="propertyPlaceholder">...</xsd:complexType>
        <xsd:element name="property-placeholder">...</xsd:element>
        <xsd:element name="property-override">...</xsd:element>
        <xsd:element name="annotation-config">...</xsd:element>
        <xsd:element name="component-scan">
            <xsd:annotation>...</xsd:annotation>
            <xsd:complexType>
                <xsd:sequence>...</xsd:sequence>
                <xsd:attribute name="base-package" type="xsd:string" use="required">...    </xsd:attribute>
                <xsd:attribute name="resource-pattern" type="xsd:string">...</xsd:attribute>
                <xsd:attribute name="use-default-filters" type="xsd:boolean" default="true">...</xsd:attribute>
                <xsd:attribute name="annotation-config" type="xsd:boolean" default="true">...</xsd:attribute>
                <xsd:attribute name="name-generator" type="xsd:string">...</xsd:attribute>
                <xsd:attribute name="scope-resolver" type="xsd:string">...</xsd:attribute>
                <xsd:attribute name="scoped-proxy">...</xsd:attribute>
            </xsd:complexType>
        </xsd:element>
        <xsd:element name="load-time-weaver">...</xsd:element>
        <xsd:element name="spring-configured">...</xsd:element>
        <xsd:element name="mbean-export">...</xsd:element>
        <xsd:element name="mbean-server">...</xsd:element>
        <xsd:complexType name="filterType">...</xsd:complexType>
    </xsd:schema>
    
    image.png

    三.标签的处理

    我们知道,注解还是xml的标签,作用都是起一个tag的标记,最终是由其他处理器去发现这些标签,并根据标签执行不同的逻辑,所以上面这些namespace和element都对应着各自的处理器,且处理器以namespaceHandler:elementHandler层次结构封装

    1.element处理器

    • spring jar 包的/META-INF/目录下,有spring.handlers文件,该文件定义了若干element 处理器,如spring-context-4.2.1.RELEASE.jar包下的/META-INF/spring.handlers文件
    http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
    http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
    http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
    http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler
    http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler
    
    • 再看ContextNamespaceHandler类
      • 针对component-scan可以看到new ComponentScanBeanDefinitionParser()
    public class ContextNamespaceHandler extends NamespaceHandlerSupport {
    
        @Override
        public void init() {
            registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
            registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
            registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
            registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
            registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
            registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
            registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
            registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
        }
    
    }
    
    • 查看父类NamespaceHandlerSupport实现子类
      • 大概有13个实现类
      • 且分布在不同的jar包中,比如AopNamespaceHandler子类在spring-aop-4.2.1.RELEASE.jar包中**
      • 如此说明我们可以定义自己namespace处理类,并保存到/META-INF/spring.handlers中
        image.png
    public class AopNamespaceHandler extends NamespaceHandlerSupport {
    
        /**
         * Register the {@link BeanDefinitionParser BeanDefinitionParsers} for the
         * '{@code config}', '{@code spring-configured}', '{@code aspectj-autoproxy}'
         * and '{@code scoped-proxy}' tags.
         */
        @Override
        public void init() {
            // In 2.0 XSD as well as in 2.1 XSD.
            registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser());
            registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser());
            registerBeanDefinitionDecorator("scoped-proxy", new ScopedProxyBeanDefinitionDecorator());
    
            // Only in 2.0 XSD: moved to context namespace as of 2.1
            registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
        }
    
    }  
    

    相关文章

      网友评论

          本文标题:003-bean xml 解析流程

          本文链接:https://www.haomeiwen.com/subject/yaecehtx.html