本文说点儿简单的。
如果你想研究基于 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
就是命名空间。