Spring源碼情操陶冶-自定義節點的解析

本文承接前文Spring源碼情操陶冶-DefaultBeanDefinitionDocumentReader#parseBeanDefinitions,特開闢出一塊新地來啃啃這塊有意思的骨頭html

自定義節點的類型

咱們經常使用的可分爲spring/springmvc兩類java

  1. spring經常使用的節點類型spring

    • context類型
    1. context-component-scan-掃描包內的全部class類並註冊爲beanDefinition到spring上下文
    2. context-property-placeholder-加載外部的資源供spring調用,經常使用${}來使用外部文件的屬性
    3. context-annotation-config-自動對註冊的beanDefinition進行註解處理,經常使用context-component-scan來代替
    • aop類型
      aop-config-AOP模式使用配置
    • task類型
    1. task-annotation-driven-任務處理配置
    2. task-executor-任務線程池配置
    3. task-schedulertask-scheduled-tasks-預先任務處理配置
  2. springmvc經常使用的節點類型跨域

    1. mvc-annotation-driven-mvc註解式配置,多與context-component-scan搭配使用
    2. mvc-interceptors-mvc攔截器配置
    3. mvc-resources-mvc靜態資源訪問配置
    4. mvc-freemarker-configurer/mvc-velocity-configurer/mvc-groovy-configurer-視圖渲染器配置
    5. mvc-cors-跨域資源訪問配置

NamespaceHandlerSupport-基礎支持抽象類

NamespaceHandlerSupportNamespaceHandler接口的直接實現類,後續的自定義節點的解析類都是繼承此類來進行擴展的。這裏咱們只關注NamespaceHandler的兩個實現方法initparsemvc

  • init()
    初始化方法,抽象類中並無對其進行復寫,主要由繼承的子類去複寫,目的是初始化自定義節點的相關解析類並保存至NamespaceHandlerSupport#parsersmap集合中cors

  • parse(Element element, ParserContext parserContext)
    主要調用方法,在Spring源碼情操陶冶-DefaultBeanDefinitionDocumentReader#parseBeanDefinitions章節中咱們提到其會調用NamespaceHandler的通用方法parse也就是此方法來進行相應節點的解析,代碼以下
@Override
    public BeanDefinition parse(Element element, ParserContext parserContext) {
        //找到相應的解析器並進行解析
        return findParserForElement(element, parserContext).parse(element, parserContext);
    }

順藤摸瓜看下NamespaceHandlerSupport#findParserForElement方法ide

private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
        //通常都是相似context-component-scan、mvc-resources這樣的節點名
        String localName = parserContext.getDelegate().getLocalName(element);
        //此處顯而易見可察覺經過parsers這個map集合獲取相應的解析器
        BeanDefinitionParser parser = this.parsers.get(localName);
        if (parser == null) {
            parserContext.getReaderContext().fatal(
                    "Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
        }
        return parser;
    }

由此得出咱們能夠稍微密切關注下子類對init()方法的複寫,即可得出相關的自定義節點對應的BeanDefinitionParser解析器this

經常使用的NamespaceHandler實現類

這裏只分析ContextNamespaceHandler-spring context空間處理類MvcNamespaceHandler-springmvc空間處理類spa

ContextNamespaceHandler-context空間處理類

先瞧瞧代碼,內部只有一個方法且也是複寫方法init()線程

@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());
    }

挑選幾個重要的解析器來分析

MvcNamespaceHandler-springmvc空間處理類

瞧瞧代碼

@Override
    public void init() {
        registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
        registerBeanDefinitionParser("default-servlet-handler", new DefaultServletHandlerBeanDefinitionParser());
        registerBeanDefinitionParser("interceptors", new InterceptorsBeanDefinitionParser());
        registerBeanDefinitionParser("resources", new ResourcesBeanDefinitionParser());
        registerBeanDefinitionParser("view-controller", new ViewControllerBeanDefinitionParser());
        registerBeanDefinitionParser("redirect-view-controller", new ViewControllerBeanDefinitionParser());
        registerBeanDefinitionParser("status-controller", new ViewControllerBeanDefinitionParser());
        registerBeanDefinitionParser("view-resolvers", new ViewResolversBeanDefinitionParser());
        registerBeanDefinitionParser("tiles-configurer", new TilesConfigurerBeanDefinitionParser());
        registerBeanDefinitionParser("freemarker-configurer", new FreeMarkerConfigurerBeanDefinitionParser());
        registerBeanDefinitionParser("velocity-configurer", new VelocityConfigurerBeanDefinitionParser());
        registerBeanDefinitionParser("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
        registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
        registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
    }

挑選重要的幾個解析器來分析

AopNamespaceHandler-aop空間處理類

簡單的瞅下代碼

@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());
    }

此處咱們就簡單的分析aop-config節點對應的解析器>>>Spring源碼情操陶冶-AOP之ConfigBeanDefinitionParser解析器

TaskNamespaceHandler-task空間處理類

TxNamespaceHandler-tx空間處理類

小結

經過分析spring與springmvc經常使用的自定義標籤解析器,但願能幫助博主以及讀者更好的瞭解spring與springmvc的工做原理,方便在分析問題時更加駕輕就熟

相關文章
相關標籤/搜索