spring源码分析之spring-web web模块分析

0 概述

spring-web的web模块是更高一层的抽象,它封装了快速开发spring-web需要的基础组件。其结构如下:

1. 初始化Initializer部分

  1.1  Servlet3.0 的ServletContainerInitializer用来支持基于代码的servlet容器配置,它使用spring的WebApplicationInitializer SPI 来代替(或者混合使用)使用传统的基于web.xml的方式。

 1.2  SpringServletContainerInitializer在兼容servlt 3.0的容器启动时,触发onStartUp方法加载并初始化该类。容器启动时假定spring web模块的jar已经存放在classpath中。加载时使用ServiceLoader的loader方法来查找spring-web模块下的META-INF/services/javax.servlet.servletContainerInitializer服务提供者配置文件。

1.3 HttpRequestHandler接口约等于HttpServlet,所有的方法集中于handleRequest方法。其实现类如下:

2. 接受请求的accept部分

   还记得我们的http请求报文吗?

GET /tutorials/other/top-20-mysql-best-practices/ HTTP/1.1 (Request line)
Host: net.tutsplus.com
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Cookie: PHPSESSID=r2t5uvjq435r4q7ib3vtdjq120
Pragma: no-cache
Cache-Control: no-cache

先了解一下rfc-2616是如何定义的?

The Accept request-header field can be used to specify certain media types which are acceptable for the response. Accept headers can be used to indicate that the request is specifically limited to a small set of desired types, as in the case of a request for an in-line image.

       Accept         = "Accept" ":"
                        #( media-range [ accept-params ] )
       media-range    = ( "*/*"
                        | ( type "/" "*" )
                        | ( type "/" subtype )
                        ) *( ";" parameter )
       accept-params  = ";" "q" "=" qvalue *( accept-extension )
       accept-extension = ";" token [ "=" ( token | quoted-string ) ]

The asterisk "*" character is used to group media types into ranges, with "*/*" indicating all media types and "type/*" indicating all subtypes of that type. The media-range MAY include media type parameters that are applicable to that range.

Each media-range MAY be followed by one or more accept-params, beginning with the "q" parameter for indicating a relative quality factor. The first "q" parameter (if any) separates the media-range parameter(s) from the accept-params. Quality factors allow the user or user agent to indicate the relative degree of preference for that media-range, using the qvalue scale from 0 to 1 (section 3.9). The default value is q=1.

      Note: Use of the "q" parameter name to separate media type
      parameters from Accept extension parameters is due to historical
      practice. Although this prevents any media type parameter named
      "q" from being used with a media range, such an event is believed
      to be unlikely given the lack of any "q" parameters in the IANA
      media type registry and the rare usage of any media type
      parameters in Accept. Future media types are discouraged from
      registering any parameter named "q".

The example

       Accept: audio/*; q=0.2, audio/basic

SHOULD be interpreted as "I prefer audio/basic, but send me any audio type if it is the best available after an 80% mark-down in quality."

If no Accept header field is present, then it is assumed that the client accepts all media types. If an Accept header field is present, and if the server cannot send a response which is acceptable according to the combined Accept field value, then the server SHOULD send a 406 (not acceptable) response.

A more elaborate example is

       Accept: text/plain; q=0.5, text/html,
               text/x-dvi; q=0.8, text/x-c

Verbally, this would be interpreted as "text/html and text/x-c are the preferred media types, but if they do not exist, then send the text/x-dvi entity, and if that does not exist, send the text/plain entity."

Media ranges can be overridden by more specific media ranges or specific media types. If more than one media range applies to a given type, the most specific reference has precedence. For example,

       Accept: text/*, text/html, text/html;level=1, */*

have the following precedence:

       1) text/html;level=1
       2) text/html
       3) text/*
       4) */*

The media type quality factor associated with a given type is determined by finding the media range with the highest precedence which matches that type. For example,

       Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
               text/html;level=2;q=0.4, */*;q=0.5

would cause the following values to be associated:

       text/html;level=1         = 1
       text/html                 = 0.7
       text/plain                = 0.3
       image/jpeg                = 0.5
       text/html;level=2         = 0.4
       text/html;level=3         = 0.7
      Note: A user agent might be provided with a default set of quality
      values for certain media ranges. However, unless the user agent is
      a closed system which cannot interact with other rendering agents,
      this default set ought to be configurable by the user.

我们再看accept部分的整体结构:

是不是有点恍然大悟或者有点小明白了?不错,accept部分就是负责协商http内容的MIME TYPE是否满足要求的。

3. 数据绑定bing部分

   在这里,绑定的意思是将不同类型的http请求上的数据设置到特定的对象object上如javabean等,支持multipart的绑定。其结构如下:

绑定支持两种方式:编程式和注解式。

其中,注解的实现由HandlerMethodInvoker触发HandlerMethodResolver来完成。

4.web客户端client部分

 

5. 上下文context部分

包含一系列web应用的applicationContext接口和用来启动根web applicationContext的contextLoaderListener。

各种applicationContext层次结构如下图:(图片来源网络,具体链接已经找不到了,请原谅)

spring-context相关内容请参照这方面的源码解析,在这里就不一一赘述了。

6. 过滤器filter

    spring也对filter进行一定程度的封装和实现,其结构如下:

7. jsf部分

支持将jsf的web层和spring的service集成在一起,并支持jsf的el解析,spring的service层驻留在spring的根webapplicationContext中。

8. method部分

   提供给spring mvc使用的方法处理类。

9. multipart部分

一个multipart的解决文件上传的方案框架,MultipartResolver继承实现了 Apache Commons FileUpload.

10. util部分

    提供了公共的工具类。

小结

   spring-web的web模块是spring框架处理web请求的基础,spring-web的http模块(http://www.cnblogs.com/davidwang456/p/4421495.html)封装http协议中client端/server端的request请求和response响应及格式的转换,如json,rss,xml等;spring-web的remoting模块包括jaxws、caucho、httpinvoker等远程调用;spring-web的web模块则在上述模块的基础上对web应用进行了进一步的封装,提供了快速开发web的能力。

注意:上述内容为本人在阅读源码时的体会和见解,不一定正确,请引用时谨慎,如发现有错误的地方,希望能给我反馈,我会尽快修改。

原文地址:https://www.cnblogs.com/davidwang456/p/4443942.html