spring mvc源码学习笔记之八

本文说点儿简单的。
如果你想研究基于 XML 配置的 spring mvc 的话,可以简单扫一眼本文。

在基于 XML 配置的 spring mvc 开发中,我们主要就是通过 spring 提供的各种标签来配置。
但是,大家是不是都有个疑问,spring 到底给我们提供了多少标签?都有哪些?子元素有哪些?属性有哪些?

当然,如果你对 XML 非常熟悉,那简单,直接看对应模块的 schema 文件就行了。
比如在 sping-webmvc 模块的 META-INF/spring.schemas 文件中就定义了如下这些 schema

http\://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd=org/springframework/web/servlet/config/spring-mvc.xsd
http\://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd=org/springframework/web/servlet/config/spring-mvc.xsd
http\://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd=org/springframework/web/servlet/config/spring-mvc.xsd
http\://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd=org/springframework/web/servlet/config/spring-mvc.xsd
http\://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd=org/springframework/web/servlet/config/spring-mvc.xsd
http\://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd=org/springframework/web/servlet/config/spring-mvc.xsd
http\://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd=org/springframework/web/servlet/config/spring-mvc.xsd
http\://www.springframework.org/schema/mvc/spring-mvc.xsd=org/springframework/web/servlet/config/spring-mvc.xsd

你点开这些链接,研究其中的内容就行了,比如 http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd 这个文件内容如下(只是部分)

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<xsd:schema xmlns="http://www.springframework.org/schema/mvc" 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/mvc" elementFormDefault="qualified" attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.org/schema/beans" schemaLocation="https://www.springframework.org/schema/beans/spring-beans-4.3.xsd"/>
<xsd:import namespace="http://www.springframework.org/schema/tool" schemaLocation="https://www.springframework.org/schema/tool/spring-tool-4.3.xsd"/>
<xsd:element name="annotation-driven">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">

xsd:documentation>
xsd:annotation>
<xsd:complexType>
<xsd:all minOccurs="0">
<xsd:element name="path-matching" minOccurs="0">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
<xsd:complexType>
<xsd:attribute name="suffix-pattern" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="trailing-slash" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="registered-suffixes-only" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="path-helper" type="xsd:string">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="path-matcher" type="xsd:string">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
xsd:complexType>
xsd:element>
<xsd:element name="message-converters" minOccurs="0">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:choice maxOccurs="unbounded">
<xsd:element ref="beans:bean">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:element>
<xsd:element ref="beans:ref">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:element>
xsd:choice>
xsd:sequence>
<xsd:attribute name="register-defaults" type="xsd:boolean" default="true">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
xsd:complexType>
xsd:element>
<xsd:element name="argument-resolvers" minOccurs="0">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
<xsd:complexType>
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element ref="beans:bean" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:element>
<xsd:element ref="beans:ref" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="java:org.springframework.web.method.support.HandlerMethodArgumentResolver"/>
tool:annotation>
xsd:appinfo>
xsd:annotation>
xsd:element>
xsd:choice>
xsd:complexType>
xsd:element>
<xsd:element name="return-value-handlers" minOccurs="0">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
<xsd:complexType>
<xsd:choice minOccurs="1" maxOccurs="unbounded">
<xsd:element ref="beans:bean" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:element>
<xsd:element ref="beans:ref" minOccurs="0" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="java:org.springframework.web.method.support.HandlerMethodReturnValueHandler"/>
tool:annotation>
xsd:appinfo>
xsd:annotation>
xsd:element>
xsd:choice>
xsd:complexType>
xsd:element>
<xsd:element name="async-support" minOccurs="0">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
<xsd:complexType>
<xsd:all minOccurs="0">
<xsd:element name="callable-interceptors" minOccurs="0">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="beans:bean" minOccurs="1" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:element>
xsd:sequence>
xsd:complexType>
xsd:element>
<xsd:element name="deferred-result-interceptors" minOccurs="0">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element ref="beans:bean" minOccurs="1" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:element>
xsd:sequence>
xsd:complexType>
xsd:element>
xsd:all>
<xsd:attribute name="task-executor" type="xsd:string">
<xsd:annotation>
<xsd:documentation source="java:org.springframework.core.task.AsyncTaskExecutor">

xsd:documentation>
<xsd:appinfo>
<tool:annotation kind="ref">
<tool:expected-type type="java:org.springframework.core.task.AsyncTaskExecutor"/>
tool:annotation>
xsd:appinfo>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="default-timeout" type="xsd:long">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
xsd:complexType>
xsd:element>
xsd:all>
<xsd:attribute name="conversion-service" type="xsd:string">
<xsd:annotation>
<xsd:element ref="beans:ref">
<xsd:annotation>
<xsd:documentation source="org.springframework.web.servlet.resource.ResourceResolver">

xsd:documentation>
xsd:annotation>
xsd:element>
xsd:choice>
xsd:sequence>
xsd:complexType>
<xsd:complexType name="resource-transformers">
<xsd:annotation>
<xsd:documentation source="org.springframework.web.servlet.resource.ResourceTransformer">

xsd:documentation>
xsd:annotation>
<xsd:sequence>
<xsd:choice maxOccurs="unbounded">
<xsd:element ref="beans:bean">
<xsd:annotation>
<xsd:documentation source="org.springframework.web.servlet.resource.ResourceTransformer">

xsd:documentation>
xsd:annotation>
xsd:element>
<xsd:element ref="beans:ref">
<xsd:annotation>
<xsd:documentation source="org.springframework.web.servlet.resource.ResourceTransformer">

xsd:documentation>
xsd:annotation>
xsd:element>
xsd:choice>
xsd:sequence>
xsd:complexType>
<xsd:complexType name="resource-chain">
<xsd:annotation>
xsd:attribute>
<xsd:attribute name="content-type" type="xsd:string">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="charset" type="xsd:string">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="resource-loader-path" type="xsd:string">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="shared-engine" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
xsd:complexType>
xsd:element>
<xsd:element name="cors">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
<xsd:complexType>
<xsd:sequence>
<xsd:element name="mapping" minOccurs="1" maxOccurs="unbounded">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
<xsd:complexType>
<xsd:attribute name="path" type="xsd:string" use="required">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="allowed-origins" type="xsd:string">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="allowed-methods" type="xsd:string">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="allowed-headers" type="xsd:string">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="exposed-headers" type="xsd:string">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="allow-credentials" type="xsd:boolean">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
<xsd:attribute name="max-age" type="xsd:long">
<xsd:annotation>
<xsd:documentation>

xsd:documentation>
xsd:annotation>
xsd:attribute>
xsd:complexType>
xsd:element>
xsd:sequence>
xsd:complexType>
xsd:element>
xsd:schema>

从这个角度入手,是没问题的。但是我感觉大多数人看了这种都头疼(除非你精通 XML)。

接下来,可以看另外一个文件 META-INF/spring.handlers 。比如,spring-webmvc 模块中,这个文件内容如下

http\://www.springframework.org/schema/mvc=org.springframework.web.servlet.config.MvcNamespaceHandler

MvcNamespaceHandler 这个类的内容如下

/*
 * Copyright 2002-2016 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package org.springframework.web.servlet.config;

import org.springframework.beans.factory.xml.NamespaceHandler;
import org.springframework.beans.factory.xml.NamespaceHandlerSupport;

/**
 * {@link NamespaceHandler} for Spring MVC configuration namespace.
 *
 * @author Keith Donald
 * @author Jeremy Grelle
 * @author Sebastien Deleuze
 * @since 3.0
 */
public class MvcNamespaceHandler extends NamespaceHandlerSupport {

	@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("groovy-configurer", new GroovyMarkupConfigurerBeanDefinitionParser());
		registerBeanDefinitionParser("script-template-configurer", new ScriptTemplateConfigurerBeanDefinitionParser());
		registerBeanDefinitionParser("cors", new CorsBeanDefinitionParser());
	}

}

看到这是不是就清晰了。

这个标签就是被类 AnnotationDrivenBeanDefinitionParser 解析的。以此类推。其他标签也是由对应的类解析的。

这里是以 spring-webmvc 模块为例来说的,其他模块如 spring-beans 、spring-context 都有对应 META-INF/spring.handlers 文件。分别用于解析对应的命名空间下的标签。
解释下命名空间的意思,就拿 来说,mvc 就是命名空间,再比如 这个标签,context 就是命名空间。

你可能感兴趣的:(Spring,spring,mvc,学习)