Spring框架之spring-web web源码完全解析
spring-web是Spring webMVC的基础,由http、remoting、web三部分组成,核心为web模块。http模块封装了http协议中的client/server端的request请求/response响应,编解码,一些格式的转换(如cbor、Rss、json、xml)。remoting模块负责远程调用,包括caucho、httpinvoker、jaxws。
spring-web的web模块封装了快速开发spring-web需要的基础组件。包括:Initializer、accept、bind、client、context、cors、filter、jsf、method、multipart、server、util。
Initializer部分:主要通过web/目录下面的SpringServletContainerInitializer和WebApplicationInitializer做初始化的工作(例如注册servlet或者filtes等)。
accept部分:主要用来负责协商http内容的MIME TYPE是否满足要求的。同一资源可以有多种表现形式,比如xml、json等。具体使用哪种表现形式,是可以协商的。这是RESTfull的一个重要特性,Spring Web MVC也支持这个功能。
bind部分:数据绑定部分,将不同类型的http请求上的数据设置到特定的对象上,如javabean等,支持multipart的绑定。绑定支持两种方式:编程式和注解式。
client部分:客户端部分,核心类RestTemplate,与许多其他Spring 模板类(例如JdbcTemplate、JmsTemplate)设计原则相同,为执行复杂任务提供了一种具有默认行为的简化方法。
context部分:上下文部分,包含了一系列web应用的WebApplicationContext,不同功能的监听器等。
cors部分:对cors跨域资源操作提供了支持。
filter部分:封装了各种不同的过滤器。
jsf部分:增加了对一种以组件为中心的用户界面构建方法的页面表示技术JSF的支持。
method部分:提供给spring mvc使用的方法处理类。
multipart部分:对rfc1867为http协议新增的文件上传功能multipart/form-data提供支持。
server部分:服务器部分。包括ServerWebExchange、WebSession、WebFilter、WebHandler等类。
util部分:提供了公共的工具类。
本文基于version为5.2.4.BUILD-SNAPSHOT的Spring源码版本进行分析,对spring-web web十二个子模块中包含的接口和类进行分析。
一、web/
1.1 SpringServletContainerInitializer
servlet规范规定,在容器启动时,会通过ServletContainerInitializer的实现类来做初始化的工作(例如注册servlet或者filtes等)。
具体使用方法为:
1、实现ServletContainerInitializer接口。(SpringServletContainerInitializer类)
2、在对应的jar包的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件。(..\spring-web\src\main\resources\META-INF\services\,tomcat默认就会去读取META-INF)
3、ServletContainerInitializer文件内容为实现类的全类名,即包名+类名。(内容为:org.springframework.web.SpringServletContainerInitializer)
SpringServletContainerInitializer类实现了ServletContainerInitializer接口。这意味着servlet(3.0以上版本)容器启动时,该类被容器自动加载并执行其onStartup(webAppInitializerClasses, servletContext)方法。
SpringServletContainerInitializer 类使用了@HandlesTypes(WebApplicationInitializer.class)注解。表明给onStartup方法传递了类路径下所有实现了WebApplicationInitializer类。spring将初始化所有这些具体实现类,并调用它们的WebApplicationInitializer#onStartup(servletContext)方法。这些类可以在其onStartup方法中,通过可编程方式注册和初始化servlet组件。
简单介绍下Servlet:
Servlet就是一个Java接口,只有5个方法的接口,Servlet接口中的5大方法:
1、void init(ServletConfig):初始化servlet,它是servlet的生命周期方法,由web容器调用一次。
2、void service(ServletRequest, ServletResponse):为传入的请求提供响应,它由容器的每个请求调用。
3、void destroy():仅被调用一次,表明servlet正在被销毁。
4、ServletConfig getServletConfig():返回ServletConfig对象。
5、String getServletInfo():返回有关servlet的信息,如作者、版权、版本等。
Servlet接口定义的是一套处理网络请求的规范,所有实现servlet的类,都要实现它的5个方法。其中最主要的是两个生命周期方法init()和destroy(),还有一个处理请求service()。也就是说所有实现servlet接口的类,或者说,所有想要处理网络请求的类,都要回答三个问题:初始化要做什么,销毁时要做什么,接受到请求时要做什么。
实现了servlet的类能处理请求吗,不能。那请求怎么来到servlet呢,通过servlet容器,比如我们最常用的tomcat。所以需要将servlet部署到一个容器中,否则servlet根本不会起作用。
容器(如tomcat)才是与客户端直接打交道的,它监听了端口,请求过来后,根据url等信息,确定要将请求交给哪个servlet去处理,然后调用那个servlet的service方法,service方法返回一个response对象,tomcat再把这个response返回给客户端。
1.2 WebApplicationInitializer
现在JavaConfig配置方式在逐步取代xml配置方式。而WebApplicationInitializer可以看做是Web.xml的替代,它是一个接口。通过实现WebApplicationInitializer,在其中可以添加servlet,listener等,在加载Web项目的时候会加载这个接口实现类,从而起到web.xml相同的作用。
WebApplicationInitializer的调用执行要通过SpringServletContainerInitializer类实现。SpringServletContainerInitializer 类使用了@HandlesTypes(WebApplicationInitializer.class)注解。表明给其onStartup方法传递了类路径下所有实现了WebApplicationInitializer类。spring将初始化所有这些具体实现类,并调用他们的WebApplicationInitializer#onStartup(servletContext)方法。
进入SpringServletContainerInitializer 类的onStartup方法:
1、先判断webAppInitializerClasses这个Set是否为空。
2、如果不为空的话,找到这个Set中不是接口,不是抽象类,并且是WebApplicationInitializer接口实现类的类,将它们保存到List中。
3、判断这个list是否为空,为空则记录日志,返回。
4、不为空的话就按照一定的顺序排序,并将它们按照一定的顺序实例化。调用每一个WebApplicationInitializer的onStartup(servletContext)方法执行。
1.3 HttpRequestHandler
Http请求处理器,一个专门用来处理Http请求,并生成对应的响应的处理器。只有一个handlerRequest方法,其处理逻辑随子类的实现不同而不同。该接口类似于javaEE中的Servlet,目的都是处理请求,产生响应结果。
1.4 HttpMediaTypeException
和媒体类型(Media Types)相关的异常的抽象基类。
1.5 HttpMediaTypeNotAcceptableException
客户端请求期望响应的媒体类型与服务器响应的媒体类型不一致造成的。例如客户端希望返回的媒体类型是json对象(application/json),服务器返回的媒体类型是一个普通的json字符串(text/plain);又或者是客户端希望返回的是html页面,服务器返回的却是json对象。
1.6 HttpMediaTypeNotSupportedException
每条HTTP 请求报文都包含一个方法。这个方法会告诉服务器要执行什么动作,不同于GET、HEAD、DELETE方法,PUT、POST、PATCH方法需要发送客户端数据,HttpRequestHandler处理这三种请求报文时,客户端数据的类型不被支持抛出的异常。
1.7 HttpRequestMethodNotSupportedException
当一个请求报文处理器不支持该请求报文的方法时抛出的异常。一些常见的HTTP方法:
GET:从服务器向客户端发送命名资源;
HEAD:仅发送命名资源响应中的HTTP 首部;
DELETE:从服务器中删除命名资源;
PUT:将来自客户端的数据存储到一个命名的服务器资源中去;
POST:将客户端数据发送到一个服务器网关应用程序;
PATCH:方法是新引入的,是对PUT方法的补充,用来对已知资源进行局部更新。
1.8 HttpSessionRequiredException
一个HttpRequestHandler需要session,但从当前请求获得不到session时抛出的异常。
二、web/accept
accept部分就是负责协商http内容的Mime Type是否满足要求的。几个HTTP请求报文示例:
GET /tools.html HTTP/1.0
User-agent: Mozilla/4.75 [en] (Win98; U)
Host: www.joes-hardware.com
Accept: text/html, image/gif, image/jpeg
Accept-language: en
GET /seasonal/index-fall.html HTTP/1.1
Host: www.joes-hardware.com
Accept: *
HEAD /seasonal/index-fall.html HTTP/1.1
Host: www.joes-hardware.com
Accept: *
rfc-2616中HTTP/1.1中标准头域Accept的语法和语义:
对于实体头域来说,发送者和接收者都既可以指客户端也可以指服务器,取决于谁发送和谁接收此实体。
Accept请求头域被用于指定哪些媒体类型的响应对请求端是可接受的。Accept头域被用于指明请求只对某些期望的媒体类型有效,例如请求一个内嵌的图像。
Accept = "Accept" ":"
#( media-range [ accept-params ] )
media-range = ( "*/*"
| ( type "/" "*" )
| ( type "/" subtype )
) *( ";" parameter )
accept-params = ";" "q" "=" qvalue *( accept-extension )
accept-extension = ";" token [ "=" ( token | quoted-string ) ]
星号”*”字符用于把媒体类型组合成一个范围,“*/*”指明了所有的媒体类型而“type/*”指明type类型的所有子类型。Media-range可能包含一个媒体类型参数。
每一个media-range可能会跟随一个或多个accept-params,以“q”参数指明一个相对的喜爱程度的质量因子。通过第一个“q”参数(如果有的话)把accept-params和media-range参数分离。喜爱程度质量因子允许用户或用户代理去指明对那个media-range 的相对喜爱程度,qvalue的范围是从0到1。缺省是q=1。
注意:利用“q”参数名字将媒体类型参数(译注:media-range里的parameter)和acceptextension分离开来是基于历史的实践。尽管这能防止任何以“q”命名的媒体类型参数应用于media-range 里,但在一个media-range 里使用“q”被认为是不可能发生的,这是因为在IANA的媒体类型注册表里是没有“q”参数的并且在Accept头域里利用媒体类型参数也是很少见。将来的媒体类型不被鼓励任何以“q”命名的参数注册。
例子:
Accept: audio/*; q=0.2, audio/basic
该例应该被解释成“我喜欢audio/basic,但是可以给我发送任何audio类型如果它最容易得到,但在喜爱程度质量要下降80%”。
如果没有Accept头域出现,那么会假设客户端能接受所有媒体类型。如果Accept头域在请求消息里出现,并且如果服务器根据联合Accept头域值发现它不能发送客户端可接受的响应,那么服务器应发送406(不可接受的)响应。
一个更加详尽的例子如下:
Accept: text/plain; q=0.5, text/html,
text/x-dvi; q=0.8, text/x-c
这可能被口头地解释成“text/html 和 text/x-c是更喜爱的媒体类型,但是如果他们不存在,那么发送text/x-dvi实体,但如果text/x-dvi也不存在,那么发送text/plain实体。
Media-range能被更具有特殊性的media-range或媒体类型覆盖。如果多个media-range应用了一个特指的类型,那么最具有特殊性的应该优先。例如:
Accept: text/*, text/html, text/html;level=1, */*
拥有下面的优先顺序:
1) text/html;level=1
2) text/html
3) text/*
4) */*
一个媒体类型的喜爱程度质量因子是和一个给定的媒体类型联系在一起的,它是由查找能最高优先匹配那个媒体类型的media-range决定的。例如:
Accept: text/*;q=0.3, text/html;q=0.7, text/html;level=1,
text/html;level=2;q=0.4, */*;q=0.5
可能会引起下面值被联系:
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
注意:一个用户代理可能会为一个特定的media-range提供一个缺省的质量值的集合。然而,除非用户代理是一个不能和其他的呈现代理交互的封闭的系统,否则这个缺省的集合应该可以被用户可设置的。
什么是内容协商:简单点说,就是同一资源,可以有多种表现形式,比如xml、json等,具体使用哪种表现形式,是可以协商的。这是RESTfull的一个重要特性,Spring Web MVC也支持这个功能。
Spring MVC REST展示内容(视图)采用的几种方式:
1、根据Http请求的header中的Accept属性的值来判读,比如:
Accept: application/xml 将返回xml格式数据
Accept: application/json 将返回json格式数据
优点:是这种方式是理想的标准方式
缺点:是由于浏览器的差异,导致发送的Accept Header头可能会不一样,从而导致服务器不知要返回什么格式的数据
2、根据扩展名来判断,比如:
/mvc/test.xml 将返回xml格式数据
/mvc/test.json 将返回json格式数据
/mvc/test.html 将返回html格式数据
缺点:丧失了同一URL的多种展现方式。在实际环境中使用还是较多的,因为这种方式更符合程序员的习惯
3、根据参数来判断
/mvc/test?format=xml 将返回xml数据
/mvc/test?format=json 将返回json数据
缺点:需要额外的传递format参数,URL变得冗余繁琐,缺少了REST的简洁风范
2.1 ContentNegotiationStrategy
策略接口,用于从请求对象中的信息中判断该请求的MediaType,即客户端需要什么类型(MediaType)的数据。
该接口主要定义了一个方法List<MediaType> resolveMediaTypes(NativeWebRequest webRequest)。该方法接受一个参数NativeWebRequest(请求对象),分析该请求对象,从而获得它的MediaType列表。
2.2 FixedContentNegotiationStrategy
该策略对象创建时固定了一组MediaType,不管请求对象是什么,都返回这组MediaType。
2.3 HeaderContentNegotiationStrategy
该策略对象分析请求头部Accept 得出该请求的一组MediaType,如果请求头部Accept未设置,返回的MediaType只包含*/*。
2.4 AbstractMappingContentNegotiationStrategy
抽象基类,通过request获取MediaType所需的Key,再根据Key找出对应的MediaType列表并返回。ParameterContentNegotiationStrategy,PathExtensionContentNegotiationStrategy,ServletPathExtensionContentNegotiationStrategy都是从该类派生出来的。
2.5 ParameterContentNegotiationStrategy
根据一个查询参数(query parameter)判断请求的MediaType,该查询参数缺省使用format`。
2.6 PathExtensionContentNegotiationStrategy
根据请求URL 路径中所请求的文件资源的扩展名部分判断请求的MediaType。
2.7 ServletPathExtensionContentNegotiationStrategy
扩展自PathExtensionContentNegotiationStrategy,将使用ServletContext#getMimeType(String)方法判断请求MediaType。
2.8 MediaTypeFileExtensionResolver
MediaType和路径扩展名解析策略的接口,例如将 json 解析成 application/json 或者反向解析。
主要定义了两个方法:List<String> resolveFileExtensions(MediaType mediaType)方法,根据指定的mediaType返回一组文件扩展名;List<String> getAllFileExtensions()方法,返回该策略接口中注册的所有文件扩展名。
2.9 MappingMediaTypeFileExtensionResolver
此类维护一些Map以及提供操作的方法,它维护了一个文件扩展名和MediaType的双向查找表。扩展名和MediaType的对应关系:一个MediaType对应N个扩展名;一个扩展名最多只会属于一个MediaType。
2.10 ContentNegotiationManager
内容协商管理器ContentNegotiationManager是Spring Web一个重要的工具类,用于判断一个请求的媒体类型MediaType列表。具体的做法是委托给它所维护的一组ContentNegotiationStrategy实例。实际上它自身也实现了接口ContentNegotiationStrategy,使用者可以直接将它作为一个ContentNegotiationStrategy使用。
另外,ContentNegotiationManager也实现了接口MediaTypeFileExtensionResolver,从而可以根据MediaType查找到相应的文件扩展名。这一点也是通过将任务委托给他所维护的一组MediaTypeFileExtensionResolver实例完成的。
ContentNegotiationManager其实就是一个组合容器:组合了一组用于判断请求媒体类型的ContentNegotiationStrategy实例;组合了一组用于根据媒体类型获取文件扩展名的MediaTypeFileExtensionResolver实例,而ContentNegotiationManager又实现了这两个接口ContentNegotiationStrategy/MediaTypeFileExtensionResolver。它对这两个接口的功能实现最终委托给了它所维护的这些实例来完成。通过这种组合-委托模式,使用者自己不用维护这些单个的ContentNegotiationStrategy/MediaTypeFileExtensionResolver的实例以及对它们的组合使用了,而是只需要通过使用ContentNegotiationManager即可。
2.11 ContentNegotiationManagerFactoryBean
用来生成ContentNegotiationManager,并使用ContentNegotiationStrategy配置它。
三、web/bind
数据绑定部分,绑定的意思是将不同类型的http请求上的数据设置到特定的对象object上如javabean等,支持multipart的绑定。绑定支持两种方式:编程式和注解式。其中,注解的实现由HandlerMethodInvoker触发HandlerMethodResolver来完成。
3.1 WebDataBinder
它的作用就是从web request 里(注意:这里指的web请求,并不一定就是ServletRequest请求)把web请求的parameters绑定到JavaBean上。
Controller方法的参数类型可以是基本类型,也可以是封装后的普通Java类型。若这个普通Java类型没有声明任何注解,则意味着它的每一个属性都需要到Request中去查找对应的请求参数。无论客户端传入的是什么类型的请求参数,最终都要以字节的形式传给服务端。而服务端通过Request的getParameter方法取到的参数也都是字符串形式的结果。所以,需要有一个把字符串形式的参数转换成服务端真正需要的类型的转换工具,在spring中这个转换工具为WebDataBinder。
3.2 ServletRequestDataBinder
从Servlet Request里把参数绑定到JavaBean里,支持multipart。
3.3 ServletRequestParameterPropertyValues
PropertyValue类:保存单个bean属性的信息和值的对象。
PropertyValues接口:包含一个或多个PropertyValue对象的容器。
MutablePropertyValues类: PropertyValues接口的默认实现。
ServletRequestParameterPropertyValues继承自MutablePropertyValues,能够查找以特定前缀(比如""spring"")加前缀分割器(默认为""_"")开头的所有property values。
3.4 ServletRequestUtils
操作request的工具类。主要用来从ServletRequest中析取被绑定的参数。
3.5 EscapedErrors
各种错误类型包装器,增加了automatic HTML escaping错误类型,在HTML视图中方便使用。通过RequestContext的getErrors方法获得该wrapped的实例。
3.6 MethodArgumentNotValidException
检验使用@Valid注解的参数失败抛出的异常。
3.7 ServletRequestBindingException
绑定时致命异常错误,这些绑定异常时不可恢复的。拓展自ServletException,为了在Servlet资源(如Filter)中方便抛出。
3.8 MissingMatrixVariableException
ServletRequestBindingException子类,当一个使用了@RequestMapping标注的方法在其参数中期望的一个matrix variable不在从URL提取出来的matrix variables时抛出的异常。
3.9 MissingPathVariableException
ServletRequestBindingException的子类,当一个使用@RequestMapping注解标注的方法在其参数中期望的一个path variable不在从URL中提取出来的URI variables中抛出的异常。
3.10 MissingRequestCookieException
ServletRequestBindingException的子类,当一个使用@RequestMapping注解标注的方法在其参数中期望的request cookie不存在时抛出的异常。
3.11 MissingRequestHeaderException
ServletRequestBindingException的子类,当一个使用@RequestMapping注解标注的方法在其参数中期望的request header不存在时抛出的异常。
3.12 MissingServletRequestParameterException
ServletRequestBindingException的子类,表示缺失了一个参数。
3.13 UnsatisfiedServletRequestParameterException
ServletRequestBindingException的子类,表示一个不满足的参数的状况。
web/bind/support
3.14 WebExchangeDataBinder
Spring5.0后提供的,对Reactive编程的Mono数据绑定提供支持。
3.15 WebRequestDataBinder
它是用于处理Spring自己定义的org.springframework.web.context.request.WebRequest的,旨在处理和容器无关的web请求数据绑定。
3.16 WebDataBinderFactory
为一个目标对象创建一个WebDataBinder实例。
3.17 DefaultDataBinderFactory
创建一个WebRequestDataBinder实例,并使用WebBindingInitializer对其进行初始化。
3.18 SpringWebConstraintValidatorFactory
该类实现了JSR-303 ConstraintValidatorFactory接口,委托给当前的Spring WebApplicationContext,用以创建自动装配的ConstraintValidator实例。
WebApplicationContext是专门为web应用准备的,允许从相对于web根目录的路劲中装载配置文件完成初始化工作。
ConstraintValidator接口实现类可以完成自定义注解校验。我们往往使用注解的方式对传入的参数进行一个格式的校验,但已有的注解不是万能的,我们在实现当前业务逻辑判断时会遇到已有注解不能校验的逻辑,我们则需要自己自定义校验注解进行对参数的校验。
3.19 WebBindingInitializer
实现此接口重写initBinder方法注册的属性编辑器是全局的属性编辑器,对所有的Controller都有效。
3.20 ConfigurableWebBindingInitializer
实现了接口WebBindingInitializer,用来初始化WebDataBinder,将请求的参数转化为对应的JavaBean,并且会结合类型、格式转换等API一起使用。
3.21 SessionAttributeStore
往后台session存储model attributes的策略接口。
3.22 DefaultSessionAttributeStore
SessionAttributeStore接口的默认实现类,用来往Web Request session(比如HttpSession)存取数据的工具类。
3.23 SessionStatus
一个简单的接口,可以在处理方法中使用,使他们可以判断会话的处理是否结束,如果结束可以紧接着进行一些清理工作。定义了两个函数:setComplete()、isComplete()。
3.24 SimpleSessionStatus
SessionStatus接口的简单实现,定义了一个标示变量complete。
3.25 WebArgumentResolver
参数解析器。
3.26 WebExchangeBindException
继承自ServerWebInputException,当数据绑定和验证失败时抛出的异常。该异常类也实现了接口BindingResult(包括它的父接口Errors),允许直接分析绑定和验证的错误。
web/bind/annotation
3.27 ControllerAdvice
此注解用于class上。使用@ControllerAdvice声明一个类来统一对所有@RequestMapping方法来做@ExceptionHandler、``@InitBinder以及@ModelAttribute`处理。
3.28 CookieValue
此注解用在@RequestMapping声明的方法的参数上,可以把HTTP cookie中相应名称的cookie绑定上去。
3.29 CrossOrigin
此注解用在class和method上用来支持跨域请求,是Spring 4.2后引入的。
3.30 DeleteMapping
使用DELETE方式进行交互。
3.31 ExceptionHandler
此注解使用在方法级别,声明对Exception的处理逻辑。可以指定目标Exception。
3.32 GetMapping
将 HTTP GET 请求映射到特定的处理程序方法。
3.33 InitBinder
此注解使用在方法上,声明对WebDataBinder的初始化(绑定请求参数到JavaBean上的DataBinder)。在controller上使用此注解可以自定义请求参数的绑定。
3.34 Mapping
元注解,用来注解一个web mapping注解。
元注解的作用就是负责注解其他注解。Java 5 定义了四个标准的元注解类型,用以提供对其它注解的功能说明。
@Target用于描述注解的范围,即注解在哪用。
@Retention用于描述注解的生命周期,表示需要在什么级别保存该注解,即保留的时间长短。
@Documented用于描述其它类型的annotation应该被作为被标注的程序成员的公共API,因此可以被例如javadoc此类的工具文档化。
@Inherited用于表示某个被标注的类型是被继承的。
3.35 MatrixVariable
此注解使用在请求handler方法的参数上,Spring可以注入matrix url中相关的值。这里的矩阵变量可以出现在url中的任何地方,变量之间用分号分隔。
3.36 ModelAttribute
被该注解定义的方法,会在该方法所在的controller的任何目标方法执行之前执行。
3.37 PatchMapping
PatchMapping注解将 HTTP Patch请求映射到特定的处理程序方法。PATCH方法是新引入的,是对PUT方法的补充,用来对已知资源进行局部更新。
3.38 PathVariable
可以使用@PathVariable将路径中的参数绑定到请求方法参数上。
3.39 PostMapping
PostMapping注解将 HTTP Post请求映射到特定的处理程序方法。
3.40 PutMapping
将 HTTP Put 请求映射到特定的处理程序方法。
3.41 RequestAttribute
此注解用在请求handler方法的参数上,用于将web请求中的属性(request attributes,服务器放入的属性值)绑定到方法参数上。
3.42 RequestBody
将请求信息的body内容绑定在程序的实体类中。
3.43 RequestHeader
此注解用在请求handler方法的参数上,用于将http请求头部的值绑定到参数上。
3.44 RequestMapping
这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上。
3.45 RequestParam
此注解用在请求handler方法的参数上,用于将http请求参数的值绑定到参数上。
3.46 RequestPart
此注解用在请求handler方法的参数上,用于将文件之类的multipart绑定到参数上。
3.47 ResponseBody
此注解将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML。
3.48 ResponseStatus
此注解用于方法和exception类上,声明此方法或者异常类返回的http状态码。可以在Controller上使用此注解,这样所有的@RequestMapping都会继承。
3.49 RestController
此注解用于class上,声明此controller返回的不是一个视图而是一个领域对象。其同时引入了@Controller和@ResponseBody两个注解。
3.50 RestControllerAdvice
此注解用于class上,同时引入了@ControllerAdvice和@ResponseBody两个注解。
3.51 SessionAttribute
注解用于方法的参数上,用于将session中的属性绑定到参数。
3.52 SessionAttributes
此注解用于type级别,用于将JavaBean对象存储到session中。一般和@ModelAttribute注解一起使用。
3.53 RequestMethod
枚举类型,枚举了HTTP请求方法:GET、HEAD、POST、PUT、PATCH、DELETE、OPTIONS、TRACE。
@RequestMapping注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上。该枚举类在RequestMapping注解类method()方法中使用。
3.54 ValueConstants
用在bind注解中的常量值。该接口只定义一个字符串常量DEFAULT_NONE。String DEFAULT_NONE = "\n\t\t\n\t\t\n\ue000\ue001\ue002\n\t\t\t\t\n";因为不能在注解的属性中使用null来表示空值,所以用这段16位Unicode的字符串(ValueConstants.DEFAULT_NONE)来表示空值,并且是不会发生这段字符串与用户定义的值是一样的情况。避免了用户给出的值却被当作是空值的情况。
四、web/client
4.1 RestTemplate
spring框架提供的RestTemplate类可用于在应用中调用rest服务,它简化了与http服务的通信方式,统一了RESTful的标准,封装了http链接, 我们只需要传入url及返回值类型即可。相较于之前常用的HttpClient,RestTemplate是一种更优雅的调用RESTful服务的方式。简而言之就是简化了发起HTTP请求以及处理响应的过程,并且支持REST。
在Spring应用程序中访问第三方REST服务与使用Spring RestTemplate类有关。RestTemplate类的设计原则与许多其他Spring 模板类(例如JdbcTemplate、JmsTemplate)相同,为执行复杂任务提供了一种具有默认行为的简化方法。
RestTemplate默认依赖JDK提供http连接的能力(HttpURLConnection),如果有需要的话也可以通过setRequestFactory方法替换为例如 Apache HttpComponents、Netty或OkHttp等其它HTTP library。
考虑到RestTemplate类是为调用REST服务而设计的,因此它的主要方法与REST的基础紧密相连,后者是HTTP协议的方法:HEAD、GET、POST、PUT、DELETE和OPTIONS。例如,RestTemplate类具有headForHeaders()、getForObject()、postForObject()、put()和delete()等方法。
4.2 RestOperations
指定了一套RESTful操作的接口,定义rest的各种操作,使用了大量的重载方法。该接口被RestTemplate类所实现。
REST: Representational State Transfer 直接翻译:表现层状态转移。全称是 Resource Representational State Transfer,通俗来讲就是:资源在网络中以某种表现形式进行状态转移。REST实际上只是一种设计风格,不是标准。基于REST构建的API就是Restful风格。
REST就是选择通过使用http协议和uri,利用client/server model对资源进行CRUD(Create/Read/Update/Delete)增删改查操作。
REST是面向资源的,而资源是通过URI进行暴露。URI的设计只要负责把资源通过合理的方式暴露出来就可以了,对资源的操作与它无关,操作是通过HTTP动词来体现的,所以REST通过URI暴露资源时,会强调不要再URI中出现动词。如GET /rest/api/getDogs 这种设计就不符合REST风格,URI里面包含了对资源的操作。 GET /rest/api/dogs满足了,它的操作是用标准的HTTP动词来体现的。
REST很好的利用HTTP本身就有的一些特征,如HTTP动词、HTTP状态码、HTTP报头等等。REST API是基于HTTP的,所以你的API应该去使用HTTP的一些标准。这样所有的HTTP客户端(如浏览器)才能够直接理解你的API(也有其他好处,如利于缓存)。REST实际上也非常强调应该利用好HTTP本来就有的特征,而不是只把HTTP当成一个传输层这么简单。
REST基础概念:
1、在REST中的一切都被认为是一种资源。
2、每个资源由URI标识。
3、同一资源有多种表现形式。例如XML,JSON。
4、使用统一的接口。处理资源使用POST、GET、PUT、DELETE操作类似创建,读取,更新和删除(CRUD)操作。
5、所以的操作都是无状态。每个请求是一个独立的请求。从客户端到服务器的每个请求都必须包含所有必要的信息,以便于理解。
4.3 RequestCallback
回调接口,用在操作ClientHTTPRequest的代码中,包括操作请求的头,写入请求体。在内部被RestTemplate类使用,应用代码中也有作用。几个工厂方法如下(工厂方法:定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。将实例化逻辑委托给子类的方法):
acceptHeaderRequestCallback(Class)}
RestTemplate#httpEntityCallback(Object)}
RestTemplate#httpEntityCallback(Object, Type)
4.4 AsyncRestTemplate
Web应用程序通常需要查询外部REST服务。 在为满足这些需求扩展应用程序时,HTTP和同步调用的本质会带来挑战:可能会阻塞多个线程,等待远程HTTP响应。
AsyncRestTemplate类,在开发REST客户端时允许非阻塞异步支持。是Spring的中心类,用于异步客户端HTTP访问。 公开与RestTemplate相似的方法,但返回ListenableFuture包装器,而不是具体的结果。AsyncRestTemplate通过getRestOperations()方法公开一个同步RestTemplate,并与该RestTemplate共享其错误处理程序和消息转换器。
默认情况下,AsyncRestTemplate依靠标准JDK工具建立HTTP连接。 您可以通过使用接受AsyncClientHttpRequestFactory的构造函数来切换使用其他HTTP库,例如Apache HttpComponents,Netty和OkHttp。默认的AsyncRestTemplate构造函数注册一个SimpleAsyncTaskExecutor来执行HTTP请求。
4.5 AsyncRestOperations
指定了一套异步RESTful操作的接口,该接口被AsyncRestTemplate类所实现。
4.6 AsyncRequestCallback
回调接口,用在操作AsyncClientHttpRequest的代码中,包括操作请求的头,写入请求体。在内部被AsyncRestTemplate类使用,应用代码中也有作用。
4.7 ResponseErrorHandler
RestTemplate请求结果的异常处理器接口,接口的第一个方法hasError用于判断HttpResponse是否是异常响应(通过状态码),接口的第二个方法handleError用于处理异常响应结果(非200状态码段)。
4.8 DefaultResponseErrorHandler
ResponseErrorHandler的默认实现。该实现类进行处理异常响应:从HttpResponse解析出Http StatusCode,如果状态码StatusCode为null,就抛出UnknownHttpStatusCodeException异常;如果StatusCode存在,则解析出StatusCode的series,也就是状态码段(除了200段,其他全是异常状态码),解析规则是StatusCode/100取整。根据状态码段,进一步抛出HttpClientErrorException。
4.9 ExtractingResponseErrorHandler
继承自DefaultResponseErrorHandler,利用HttpMessageConverter对象转换器 将HTTP错误响应转换RestClientException,需要指定ResponseErrorHandler。
4.10 ResponseExtractor
解析HTTP响应的数据,从Response中提取数据,通过它来从ClientHttpResponse提取出指定内容(比如请求头、请求Body体等)。
4.11 HttpMessageConverterExtractor
返回值提取器,实现接口ResponseExtractor。
4.12 MessageBodyClientHttpResponseWrapper
ClientHttpResponse的包装类,通过读取输入流来判断这个响应是报文否包括响应体,响应体长度是否为0(如:empty)。
4.13 HttpServerErrorException
当接收到HTTP 5XX(服务器本身发生错误)抛出的异常。
4.14 HttpStatusCodeException
基于HttpStatus状态码异常的抽象类。
4.15 RestClientException
服务器响应错误导致请求失败抛出的异常,由RestTemplate抛出,由ResponseErrorHandler#hasError(ClientHttpResponse)确定与否。
4.16 RestClientResponseException
包含HTTP响应数据的异常的基类。
4.17 ResourceAccessException
I/O error发生时抛出的异常。
4.18 HttpClientErrorException
当接收到HTTP 4xx(客户端错误状态码)时抛出的异常。
4.19 UnknownHttpStatusCodeException
当接收到一个未知的HTTP状态码时抛出的异常。
web/client/support
4.20 RestGatewaySupport
作为需要REST access的应用类的基类使用,需要设置一个ClientHttpRequestFactory或者RestTemplate实例。
五、web/context
5.1 WebApplicationContext
Web应用上下文 ,专门为web应用准备。它允许从相对于web根目录的路径中装载配置文件完成初始化工作,从WebApplicationContext中可以获得ServletContext的引用,整个Web应用上下文对象将作为属性放置在ServletContext中,以便web应用可以访问spring上下文。spring中提供WebApplicationContextUtils的getWebApplicationContext(ServletContext src)方法来获得WebApplicationContext对象。
5.2 ConfigurableWebApplicationContext
扩展了WebApplicationContext,它允许通过配置的方式实例化,同时设置两个重要方法:
1、setServletContext(ServletContext context) 为spring设置web应用上下文,以便两者整合。
2、setConfigLocations(String[]locations) 设置Spring配置的文件地址。
5.3 ConfigurableWebEnvironment
ConfigurableWebEnvironment:继承自ConfigurableEnvironment,并且提供配置Servlet上下文和Servlet参数的功能。
5.4 ContextCleanupListener
Web应用监听器,用来清除在Servlet上下文中使用过后残留的属性。ServletContext,当WEB服务器启动时,会为每一个WEB应用程序创建一块共享的存储区域。ServletContext在WEB服务器启动时创建,服务器关闭时销毁。
5.5 AbstractContextLoaderInitializer
该抽象类只是为了创建ContextLoaderListener,并通过抽象方法createRootApplicationContext创建的RootApplicationContext注入进Servlet容器事件中。
5.6 ContextLoader
应用程序上下文Context是Spring管理的bean所在的容器。上下文加载器ContextLoader负责构建应用程序上下文。
5.7 ContextLoaderListener
ContextLoaderListener监听器的作用就是启动Web容器时,自动装配ApplicationContext的配置信息。因为它实现了ServletContextListener这个接口,在web.xml配置这个监听器,启动容器时,就会默认执行它实现的方法。
ContextLoaderListener调用contextInitialized方法完成Spring上下文初始化;调用contextDestroyed方法完成Spring上下文销毁。可自行定义ContextLoaderListener的子类,进而在上下文启动与销毁时加入自定义功能。
5.8 ServletConfigAware
ServletConfig是针对特定的Servlet的参数或属性。当一个servlet被实例化后,对任何客户端在任何时候访问有效,但仅对本servlet有效,一个servlet的ServletConfig对象不能被另一个servlet访问。
容器初始化一个servlet时,会为这个servlet建一个唯一的ServletConfig。容器从web.xml读出Servlet初始化参数,并把这些参数交给ServletConfig,然后把ServletConfig传递给servlet的init(ServletConfig config)方法。
ServletConfigAware接口会被希望得到ServletConfig通知的对象所实现。
5.9 ServletContextAware
当 容器启动时,容器会为每个 Web 应用创建一个唯一的 ServletContext 对象代表当前的 Web 应用,该对象封装了当前 Web 应用的所有信息。可以利用该对象获取 Web 应用程序的初始化信息、读取资源文件等。
一个web应用对应一个ServletContext实例,一个WEB应用中的所有Servlet共享同一个ServletContext对象,因此Servlet对象之间可以通过ServletContext对象通讯。Spring中,凡是实现ServletContextAware接口的类,都可以取得ServletContext。
web/context/annotation
5.10 ApplicationScope
该注解是@Scope的一个特例。
如果把变量放到application里,就说明它的作用域是application,它的有效范围是整个应用。 整个应用是指从应用启动,到应用结束。没有说“从服务器启动,到服务器关闭”,是因为一个服务器可能部署多个应用,当然你关闭了服务器,就会把上面所有的应用都关闭了。 application作用域里的变量,它们的存活时间是最长的,如果不进行手工删除,它们就一直可以使用。
@Scope注解是spring Ioc容器中的一个作用域,在 Spring IoC 容器中具有以下几种作用域:基本作用域singleton(单例)、prototype(多例),Web 作用域(reqeust、session、globalsession),自定义作用域。
1、singleton单例模式: 全局有且仅有一个实例。
2、prototype原型模式:每次获取Bean的时候会有一个新的实例。
3、request: request表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP request内有效。
4、session:session作用域表示该针对每一次HTTP请求都会产生一个新的bean,同时该bean仅在当前HTTP session内有效。
5、globalsession: global session作用域类似于标准的HTTP Session作用域,不过它仅仅在基于portlet的web应用中才有意义。
5.11 RequestScope
该注解是@Scope的一个特例。
如果把变量放到request里,就说明它的作用域是request,它的有效范围是当前请求周期。 所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。
5.12 SessionScope
该注解是@Scope的一个特例。
如果把变量放到session里,就说明它的作用域是session,它的有效范围是当前会话。所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。也就是说,只要用户不关浏览器,服务器就有办法知道这些请求是一个人发起的,整个过程被称为一个会话(session),而放到会话中的变量,就可以在当前会话的所有请求里使用。
web/context/request
5.13 AbstractRequestAttributes
RequestAttributes接口实现类的抽象基类,提供了一个请求完成机制用于请求特定的销毁回调和更新访问过的会话属性。
5.14 AbstractRequestAttributesScope
实现Scope接口的抽象基类,Request和Session作用域对应的Scope接口实例均继承自该基类。
5.15 SessionScope
作用域是session,它的有效范围是当前会话。所谓当前会话,就是指从用户打开浏览器开始,到用户关闭浏览器这中间的过程。这个过程可能包含多个请求响应。
5.16 RequestScope
作用域是request,它的有效范围是当前请求周期。 所谓请求周期,就是指从http请求发起,到服务器处理结束,返回响应的整个过程。
5.17 DestructionCallbackBindingListener
该类是Servlet HttpSessionBindingListener监听器接口的适配器,封装了一个会话销毁的回调函数。HttpSessionBindingListener 可以监听实现了该接口的对象在 Session 中被添加或者移除的事件。
5.18 RequestContextListener
RequestContextListener用于监听用户的请求,当一个用户发送一个请求,会将用户的请求request对象保存在RequestContextHolder中的requestAttributesHolder本地线程池中,当用户的请求执行完毕,会清除RequestContextHolder中的requestAttributesHolder本地线程池中的request对象。
5.19 RequestAttributes
Request相关的属性对象的抽象。
5.20 FacesRequestAttributes
RequestAttributes适配器,适配一个JSF javax.faces.context.FacesContext,在JSF环境中使用,封装当前的FacesContext。
5.21 ServletRequestAttributes
基于Servlet的RequestAttributes接口的实现。
5.22 WebRequest
Web请求的通用接口。 主要用于通用Web请求拦截器,使它们可以访问通用请求元数据,而不是用于实际处理请求。
5.23 NativeWebRequest
拓展自WebRequest接口,暴露真正的request和response对象。
5.24 ServletWebRequest
继承ServletRequestAttributes、实现NativeWebRequest接口,适配javax.servlet.http.HttpServletRequest。
5.25 FacesWebRequest
WebRequest适配器,适配一个JSF javax.faces.context.FacesContext。需要JSF2.1或者更高的版本。
Java Server Faces (JSF) 是一种用于构建Java Web 应用程序的标准框架(是Java Community Process 规定的JSR-127标准)。它提供了一种以组件为中心的用户界面(UI)构建方法,从而简化了Java服务器端应用程序的开发。
5.26 WebRequestInterceptor
WebRequestInterceptor接口同HandlerInterceptor接口一样定义了三个方法:preHandle 、postHandle 以及afterCompletion。两个接口的方法名都相同,调用次序也相同。即preHandle是在请求处理之前调用;postHandle实在请求处理之后,视图渲染之前调用;afterCompletion是在视图渲染之后调用。这三个方法都传递了同一个参数WebRequest 。
5.27 AsyncWebRequestInterceptor
AsyncWebRequestInterceptor继承自WebRequestInterceptor接口,增加了一个异步请求处理时调用的回调方法。
5.28 RequestContextHolder
持有上下文的Request容器。通过RequestContextHolder的静态方法可以随时随地取到当前请求的request对象。
web/context/request/async
5.29 AsyncRequestTimeoutException
一个异步请求超时时抛出的异常。默认情况下,这个异常会被当做503错误(503状态码,Service Unavailable,由于超载或系统维护,服务器暂时的无法处理客户端的请求)进行处理。或者应用也可以注册一个DeferredResultProcessingInterceptor或CallableProcessingInterceptor来处理这个超时。注册可以通过MVC Java配置或MVC XML命名空间或直接通过RequestMappingHandlerAdapter的属性。
5.30 AsyncWebRequest
异步请求接口,继承NativeWebRequest,增加了支持异步请求处理的方法。
5.31 CallableInterceptorChain
调用CallableProcessingInterceptor的辅助类。
5.32 CallableProcessingInterceptor
Callable拦截器。
5.33 CallableProcessingInterceptorAdapter
抽象类实现CallableProcessingInterceptor接口,空实现。
5.34 DeferredResult
递延结果,在两个线程中传递的对象结果。实现Comparable接口以保证加入PriorityQueue队列的正确顺序。
5.35 DeferredResultInterceptorChain
调用DeferredResultProcessingInterceptor的辅助类
5.36 DeferredResultProcessingInterceptor
DeferredResult处理过程拦截器。在start async前,超时后/异步处理完成后/网络超时后触发拦截。
5.37 DeferredResultProcessingInterceptorAdapter
抽象类实现DeferredResultProcessingInterceptor,做空实现。
5.38 StandardServletAsyncWebRequest
继承ServletWebRequest,实现AsyncWebRequest、AsyncListener,一个标准异步web请求的实现类。
5.39 TimeoutCallableProcessingInterceptor
继承CallableProcessingInterceptorAdapter,实现超时处理方法。
5.40 TimeoutDeferredResultProcessingInterceptor
继承DeferredResultProcessingInterceptorAdapter,实现超时处理方法。
5.41 WebAsyncManager
对Callables和DeferredResults启动的管理,包括拦截器的注入,Excutor的注入等,异步处理的入口类。
5.42 WebAsyncTask
web异步任务,包含一个Callable类,一个超时时间,一个任务执行着或名字。
5.43 WebAsyncUtils
实现getAsyncManager()和createAsyncWebRequest()方法。
web/context/support
5.44 AbstractRefreshableWebApplicationContext
实现了ConfigurableWebApplicationContext和ThemeSource接口,主要是用于web环境下。在web程序启动的时候,提供一个configLocations属性,通过ConfigurableWebApplicationContext接口来进行填充。实现该接口主要就是实现loadBeanDefinitions方法,来实现你自己的bean定义的加载逻辑。
5.45 AnnotationConfigWebApplicationContext
继承自AbstractRefreshableWebApplicationContext,接受注解的类作为输入(特殊的@Configuration注解类,一般的@Component注解类,与JSR-330兼容的javax.inject注解)。允许一个一个的注入,同样也能使用类路径扫描。对于web环境,基本上是和AnnotationConfigApplicationContext等价的。使用AnnotatedBeanDefinitionReader来对注解的bean进行处理,使用ClassPathBeanDefinitionScanner来对类路径下的bean进行扫描。
5.46 GenericWebApplicationContext
继承自GenericApplicationContext,实现了ConfigurableWebApplicationContext和ThemeSource接口。该类设计的目的不是在web.xml中进行声明式的安装,而是编程式的安装,例如使用WebApplicationInitializers来构建内嵌的上下文。该接口在ConfigurableWebApplicationContext的内容都是一个伪实现,调用其中的大多数方法都会抛出异常。他实现了ThemeSource接口,设计的目的主要是用于消息的国际化。
5.47 GroovyWebApplicationContext
继承自AbstractRefreshableWebApplicationContext,实现了GroovyObject接口,接受能被GroovyBeanDefinitionReader所理解的groovy bean定义脚本和XML文档配置。对于web环境,基本上是和GenericGroovyApplicationContext是等价的。对于根上下文,默认的配置文件路径是/WEB-INF/applicationContext.groovy,对于命名空间为test-servlet的上下文,默认的配置文件路径是/WEB-INF/test-servlet.xml(就像servlet-name为test的DispatcherServlet实例)。
5.48 StaticWebApplicationContext
继承自StaticApplicationContext,实现了ConfigurableWebApplicationContext和ThemeSource接口。该接口主要是用在测试的环境,不用于产品环境。
5.49 XmlWebApplicationContext
继承自AbstractRefreshableWebApplicationContext,用于web容器的应用上下文,接受能被XmlBeanDefinitionReader所理解的XML文档配置。对于根上下文,默认的配置文件路径是/WEB-INF/applicationContext.xml,对于命名空间为test-servlet的上下文,默认的配置文件路径是/WEB-INF/test-servlet.xml(就像servlet-name为test的DispatcherServlet实例)。
5.50 ServletContextAttributeExporter
接受Spring定义的对象并将其公开为 ServletContext属性。通常,bean引用转换成Spring定义的bean,这些bean作为ServletContext属性用。
ServletContext是javax.servlet包内定义的接口,Web容器会为每个Web程序构造一个实现该接口的对象实例,通过这个对象,Servlet可以和web容器进行交互,如获取Web容器版本号,通过Web容器的日志机制记录信息等;也可以和同一Web程序的其他Servlet进行交流,如可以通过该对象的属性来共享数据。
5.51 ServletContextAttributeFactoryBean
FactoryBean接口实现类,用来获取一个指定的、存在的ServletContext属性。
5.52 ServletContextParameterFactoryBean
FactoryBean接口实现类,用来获取一个指定的、存在的ServletContext参数。
5.53 ServletContextAwareProcessor
FactoryBean接口实现类,用来获取一个指定的ServletContext初始参数(在web.xml中定义的一个"context-param")。
5.54 ServletContextLiveBeansView
LiveBeansView子类,在web应用中寻找所有的ApplicationContexts,暴露在ServletContext属性中。
5.55 ServletContextResource
Spring提供了ServletContextResource类来访问Web Context下相对路径下的资源,ServletContextResource构造器接受一个代表资源位置的字符串参数,该资源位置是相对于Web应用根路径的位置。
使用ServletContextResource访问的资源, 也可通过文件IO访问或URL访问。通过java.io.File访问要求资源被解压缩,而且在本地文件系统中;但使用ServletContextResource进行访问时则无须资源是否被解压缩出来,或则直接存放在JAR文件中,总可通过Servlet容器访问。
5.56 ServletContextPropertySource
Spring3.1提供了新的属性管理API,而且功能非常强大且很完善,对于一些属性配置信息都应该使用新的API来管理。
PropertySource是新的属性管理API,一个抽象类,它包含一个source和一个name。source可以是map或其他,通常是一组键值对。
ServletContextPropertySource的属性来自ServletContext上下文初始化参数等等。
5.57 ServletConfigPropertySource
ServletConfigPropertySource的源为ServletConfig。
5.58 ServletContextResourceLoader
继承自DefaultReourceLoader,重写了getResourceByPath(String path)方法,该类的扩展功能是可以从Servlet上下文的根目录加载资源。
5.59 ServletContextResourcePatternResolver
ServletContext-aware的PathMatchingResourcePatternResolver的子类,能够通过ServletContext#getResourcePaths方法在web应用根目录下查找所有匹配额资源。转到其父文件系统查找其他资源。
5.60 ServletContextScope
表示其生命周期、作用范围是ServletContext。
ServletContext是一个全局的储存信息的空间,服务器开始,其就存在,服务器关闭,其才释放。request,一个用户可有多个;session,一个用户一个;而servletContext,所有用户共用一个。
运行在Java虚拟机中的每一个Web应用程序都有一个与之相关的Servlet上下文。ServletContext对象是Web服务器中的一个已知路径的根。一个ServletContext对象表示了一个Web应用程序的上下文。
5.61 ContextExposingHttpServletRequest
HttpServletRequest装饰器,使得在一个给定的WebApplicationContext中的所有Spring beans能够当成请求属性进行存取。
5.62 HttpRequestHandlerServlet
一简单的HttpServlet,代理一个在Spring root WebApplicationContext中定义的HttpRequestHandler bean。目标bean的名字必须和在web.xml中定义的HttpRequestHandlerServlet servlet-name匹配。
5.63 LiveBeansViewServlet
暴露LiveBeansView MBean的Servlet。为当前的beans和它们在所有ApplicationContexts中的依赖做一个json镜像。
通常我们的Bean都是由Spring启动时通过读取配置加载进Spring容器的,我们可以让Spring去管理我们的Bean的生成、配置以及Bean与Bean之间的依赖。但是Spring一旦启动完毕,再想去修改Bean的配置,就要用到JMX了。JMX技术的前提就是你得提供MBean,把我们的Spring Bean变为Mbean。
JMX(Java Management Extensions,即Java管理扩展)是一个为应用程序、设备、系统等植入管理功能的框架。
5.64 RequestHandledEvent
请求处理事件,当一个请求被处理完成时发布。
5.65 ServletRequestHandledEvent
RequestHandledEvent的子类,增加了servlet-specific上下文信息。
5.66 SpringBeanAutowiringSupport
工具类,主要用来对Spring Web Application上下文的类提供@Autowired注入功能。
5.67 StandardServletEnvironment
Environment接口的实现类,被Servlet web应用所使用。所有web相关的ApplicationContext类默认都会初始化一个实例。
5.68 WebApplicationContextUtils
抽象类,其提供了一个很便利的方法来获取spring应用的上下文即WebApplicationContext。
5.69 WebApplicationObjectSupport
在WebApplicationContext中运行的应用对象的功能父类,提供了getWebApplicationContext()、getServletContext()、getTempDir()等方法。
六、web/cors
6.1 CorsConfiguration
具体封装跨域配置信息的pojo。
6.2 CorsConfigurationSource
request与跨域配置信息映射的容器。
6.3 CorsProcessor
具体进行跨域操作的类。
6.4 CorsUtils
基于CORS W3C recommendation的跨域资源请求处理的工具类。
6.5 DefaultCorsProcessor
CorsProcessor接口的默认实现。
6.6 UrlBasedCorsConfigurationSource
存储request与跨域配置信息的容器。
web/cors/reactive
6.7 CorsConfigurationSource
request与跨域配置信息映射的容器。
6.8 CorsProcessor
具体进行跨域操作的类。
6.9 CorsUtils
基于CORS W3C recommendation的跨域资源响应式请求处理的工具类。
6.10 CorsWebFilter
WebFilter接口的实现类,处理CORS 跨域中的 preflight 请求,借助于CorsProcessor接口的实现类(默认为DefaultCorsProcessor)对CORS请求进行拦截,目的是在CorsConfigurationSource容器中添加相关的CORS响应头(比如Access-Control-Allow-Origin)。
6.11 DefaultCorsProcessor
CorsProcessor接口的默认实现。
6.12 UrlBasedCorsConfigurationSource
存储响应式request与跨域配置信息的容器。
七、web/filter
Spring的web包中有很多过滤器,这些过滤器位于org.springframework.web.filter,实现了javax.servlet.Filter,实现方式有以下几类:
1、直接实现Filter,这一类过滤器只有CompositeFilter。
2、继承抽象类GenericFilterBean,该类实现了javax.servlet.Filter,这一类的过滤器只有一个,即DelegatingFilterProxy。
3、继承抽象类OncePerRequestFilter,该类为GenericFilterBean的直接子类,这一类过滤器包括CharacterEncodingFilter、HiddenHttpMethodFilter、HttpPutFormContentFilter、RequestContextFilter和ShallowEtagHeaderFilter。
4、继承抽象类AbstractRequestLoggingFilter,该类为OncePerRequestFilter的直接子类,这一类过滤器包括CommonsRequestLoggingFilter、Log4jNestedDiagnosticContextFilter和ServletContextRequestLoggingFilter。
7.1 CompositeFilter
混合过滤器,通过将加入各种过滤器逻辑集filters加入到该混合器,按照过滤链FilterChain进行统一处理。
7.2 GenericFilterBean
抽象类GenericFilterBean实现了javax.servlet.Filter、org.springframework.beans.factory.BeanNameAware、org.springframework.context.EnvironmentAware、org.springframework.web.context.ServletContextAware、org.springframework.beans.factory.InitializingBean和org.springframework.beans.factory.DisposableBean六个接口,作用如下:
1、Filter,实现过滤器。
2、BeanNameAware,实现该接口的setBeanName方法,便于Bean管理器生成Bean。
3、EnvironmentAware,实现该接口的setEnvironment方法,指明该Bean运行的环境。
4、ServletContextAware,实现该接口的setServletContextAware方法,指明上下文。
5、 InitializingBean,实现该接口的afterPropertiesSet方法,指明设置属性的操作。
6、DisposableBean,实现该接口的destroy方法,用于回收资源。
7.3 DelegatingFilterProxy
该类其实并不能说是一个过滤器,它的原型是FilterToBeanProxy,即将Filter作为spring的bean,由spring来管理。该类提供了在web.xml和application context之间的联系。
有以下几个参数可以设置:
1、contextAttribute,使用委派Bean的范围,其值必须从org.springframework.context.ApplicationContext.WebApplicationContext中取得,默认值是session;其他可选的有request、globalSession和application。
2、targetFilterLifecycle,是否调用Filter的init和destroy方法,默认为false。
3、targetBeanName,被代理的过滤器的bean的名字,该bean的类必须实现Filter接口。
7.4 OncePerRequestFilter
该类为GenericFilterBean的直接子类,它保留了GenericFilterBean中的所有方法并对之进行了扩展,在oncePerRequestFilter中的主要方法是doFilter。
7.5 CharacterEncodingFilter
该过滤器是配置编码格式的。服务器启动的时候就会创建Filter,将init-param中的参数加载,注入到CharacterEncodingFilter 类中,浏览器每次发送请求都会经过这个过滤器,然后调用doFilterInternal。
7.6 HiddenHttpMethodFilter
html中form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,spring3添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求。
7.7 HttpPutFormContentFilter
由HiddenHttpMethodFilter可知,html中的form的method值只能为post或get,我们可以通过HiddenHttpMethodFilter获取put表单中的参数键值对,而在Spring3中获取put表单的参数键值对还有另一种方法,即使用HttpPutFormContentFilter过滤器。
HttpPutFormContentFilter过滤器的作为就是获取put表单的值,并将之传递到Controller中标注了method为RequestMethod.put的方法中。
与HiddenHttpMethodFilter不同,在form中不用添加参数名为_method的隐藏域,且method不必是post,直接写成put,但该过滤器只能接受enctype值为application/x-www-form-urlencoded的表单。
7.8 RequestContextFilter
这是在Spring2.0时添加的类,通过LocaleContextHolder和RequestContextHolder把Http request对象基于LocalThread绑定到请求提供服务的线程上。现在一般使用DispatcherServlet这个*分发器。现在RequestContextFilter过滤器主要用于第三方的Servlet,如JSF的FacesServlet。在Spring2.5之前都是使用该过滤器配置。
7.9 ShallowEtagHeaderFilter
ShallowEtagHeaderFilter是spring提供的支持ETag的一个过滤器,所谓ETag是指被请求变量的实体值,是一个可以与Web资源关联的记号,而Web资源可以是一个Web页,也可以是JSON或XML文档,服务器单独负责判断记号是什么及其含义,并在HTTP响应头中将其传送到客户端。
7.10 CorsFilter
跨域请求过滤器。
7.11 FormContentFilter
该过滤器为HTTP的PUT、 PATCH和 DELETE请求解析表单数据,并暴露它为Servlet请求参数。默认情况下,Servlet spec仅要求对HTTP post进行此过滤。
7.12 RelativeRedirectResponseWrapper
Response包装器,主要在RelativeRedirectFilter和 ForwardedHeaderFilter中使用。
7.13 ForwardedHeaderFilter
RFC 7239提出了一个标准化的Forwarded头部,来携带反向代理的基本信息,用于替代X-Forwarded系列及X-Real-IP等非标准化的头部。而ForwardedHeadersFilter提供了Forwarded头部的转发支持。
7.14 RelativeRedirectFilter
Servlet过滤器,将request 请求暴露给当前的线程,主要通过org.springframework.context.i18n.LocaleContextHolder和RequestContextHolder。该过滤器在web.xml中注册。
7.15 AbstractRequestLoggingFilter
上下文信息过滤器 ,定义了两个方法beforeRequest和afterRequest分别用于设定过滤前后执行的操作,它有三个子类,分别是CommonsRequestLoggingFilter、ServletContextRequestLoggingFilter和Log4jNestedDiagnosticContextFilter,这三个子类分别实现了各自的beforeRequest和afterRequest。
7.16 CommonsRequestLoggingFilter
继承自AbstractRequestLoggingFilter,CommonsRequestLoggingFilter在过滤前后分别打印出一段debug的信息。
7.17 ServletContextRequestLoggingFilter
继承自AbstractRequestLoggingFilter,ServletContextRequestLoggingFilter在过滤前后分别向日志文件中写入一段日志信息,日志文件可由log4j.properties等指定。
web/filter/reactive。
7.18 ForwardedHeaderFilter
从"Forwarded"和"X-Forwarded-*"头部提取值,用来重写请求报文的URI。
7.19 HiddenHttpMethodFilter
响应式的webFilter,html中form表单只支持GET与POST请求,而DELETE、PUT等method并不支持,spring3添加了一个过滤器,可以将这些请求转换为标准的http方法,使得支持GET、POST、PUT与DELETE请求。
7.20 ServerWebExchangeContextFilter
在响应式Context中插入属性(属性名EXCHANGE_CONTEXT_ATTRIBUTE),使得当前的ServerWebExchange可获得。在想访问ServerWebExchange但是又不显示的将其传奇给参与处理请求的组件时有用。
ServerWebExchange 命名为 服务网络交换器 ,存放着重要的请求-响应属性、请求实例和响应实例等等。
八、web/jsf
JavaServer Faces (JSF) 是一种用于构建Java Web 应用程序的标准框架(是Java Community Process 规定的JSR-127标准)。它提供了一种以组件为中心的用户界面(UI)构建方法,从而简化了Java服务器端应用程序的开发。它是一种页面表示技术。
8.1 DecoratingNavigationHandler
JSF NavigationHandler实现类的基类,用来装饰原始的NavigationHandler。
8.2 DelegatingNavigationHandlerProxy
JSF NavigationHandler实现类,代理从Spring root WebApplicationContext容器中获取的NavigationHandler bean。
在faces-config.xml文件中配置该handler proxy。如下:
<pre class=""code"">
<application>
...
<navigation-handler>
org.springframework.web.jsf.DelegatingNavigationHandlerProxy
</navigation-handler>
...
</application>
</pre>
8.3 DelegatingPhaseListenerMulticaster
JSF PhaseListener接口实现类,代理一个或多个从Spring root WebApplicationContext容器中获取的Spring-managed PhaseListener bean。
在faces-config.xml文件中配置该listener multicaster。如下:
<pre class=""code"">
<application>
...
<phase-listener>
org.springframework.web.jsf.DelegatingPhaseListenerMulticaster
</phase-listener>
...
</application>
</pre>
8.4 FacesContextUtils
为一个JSF FacesContext提取Spring的root WebApplication提供功能函数。用于在基于JSF框架的代码中访问Spring的application context情况下。
它类似于Spring中为ServletContext提供功能函数的WebApplicationContextUtils,该类是为FacesContext提供工具包。
web/jsf/el
8.5 SpringBeanFacesELResolver
JSF ELResolver接口的实现类,代理Spring的root WebApplicationContext。将名称引用解析成Spring定义的beans。
在faces-context.xml文件中配置该解析器如下:
<pre class=""code"">
<application>
...
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
</application>
</pre>
8.6 WebApplicationContextFacesELResolver
继承自JSF ELResolver,暴露Spring的WebApplicationContext一个实例,该实例变量的名字为"webApplicationContext"。
九、web/method
9.1 ControllerAdviceBean
该类关于@ControllerAdvice注解的相关信息,spring管理bean,并不要求一定要对其进行实例化。使用函数findAnnotatedBeans(ApplicationContext)可以来查找这种bean。这种bean可以被任何对象创建,包括没有加@ControllerAdvice注解的对象。
对于@ControllerAdvice,我们比较熟知的用法是结合@ExceptionHandler用于全局异常的处理,但其作用不仅限于此。ControllerAdvice拆分开来就是Controller Advice,Advice用于封装一个切面所有属性的,包括切入点和需要织入的切面逻辑。这里ContrllerAdvice也可以这么理解,其抽象级别应该是用于对Controller进行“切面”环绕的,而具体的业务织入方式则是通过结合其他的注解来实现的。@ControllerAdvice是在类上声明的注解,其用法主要有三点:
结合方法型注解@ExceptionHandler,用于捕获Controller中抛出的指定类型的异常,从而达到不同类型的异常区别处理的目的;
结合方法型注解@InitBinder,用于request中自定义参数解析方式进行注册,从而达到自定义指定格式参数的目的;
结合方法型注解@ModelAttribute,表示其标注的方法将会在目标Controller方法执行之前执行。
9.2 HandlerMethod
封装了处理函数的信息,包括getMethod()、getBean()。提供了对方法的参数、返回值、注解等等方便的存取方法。
9.3 HandlerTypePredicate
继承自Predicate接口。Predicate接口是JDK8 提供的函数式接口,提供一个抽象方法test, 接受一个参数,根据这个参数进行一些判断,返回判断结果 true/false。
web/method/annotation
9.4 AbstractCookieValueMethodArgumentResolver
抽象基类,用来解析带@CookieValue注解的方法参数。实现的子类会从请求报文中将cookie值提取出来。@CookieValue注解主要是将请求的Cookie数据,映射到功能处理方法的参数上。
9.5 AbstractNamedValueMethodArgumentResolver
该抽象基类用来从命名值(named value)解析方法参数。如请求参数、请求的头部信息、URL路径变量都是命名值。每一个都有一个名字,一个必要的标志、一个默认值。
9.6 AbstractWebArgumentResolverAdapter
使用@WebArgumentResolver的基类,用于向后兼容适配WebArgumentResolver。
9.7 ErrorsMethodArgumentResolver
处理Errors子类参数。
9.8 ExceptionHandlerMethodResolver
在一个给定的类(包括它所有的子类)中找到用@ExceptionHandler注解的方法,然后帮助解析一个给定Exceptin到exception types。
9.9 ExpressionValueMethodArgumentResolver
解析@Value注解的参数。
9.10 RequestHeaderMapMethodArgumentResolver
处理使用@RequestHeader注解的map参数。
9.11 RequestHeaderMethodArgumentResolver
解析使用@RequestHeader注解的参数,不包括map类型。
9.12 RequestParamMapMethodArgumentResolver
处理使用@RequestParam注解的map参数。
9.13 RequestParamMethodArgumentResolver
解析从request流中获取值的参数,如@RequestParam、MultipartFile、Part,默认使用时解析基本参数。
9.14 SessionStatusMethodArgumentResolver
处理SessionStatus类型参数。
9.15 SessionAttributesHandler
SessionAttributesHandler用来处理@SessionAttributes注释的参数,不过它只是做一些宏观的事情,比如,哪个Handler都可以缓存哪些参数、某个参数在当前的SessionAttributes中是否存在、如何同时操作多个参数等,而具体的存储工作是交给SessionAttributeStore去做的,不过SessionAttributeStore并不是保存数据的容器,而是用于保存数据的工具,具体保存数据的容器默认使用的是Session。
9.16 ModelFactory
ModelFactory是用来维护Model的,具体包含两个功能:1、初始化Model。2、处理器执行后将Model中相应的参数更新到SessionAttributes中。
9.17 InitBinderDataBinderFactory
通过@InitBinder注解的方法来初始化WebDataBinder。
9.18 MapMethodProcessor
处理map类型参数。
9.19 ModelMethodProcessor
处理model类型参数。
9.20 ModelAttributeMethodProcessor
解析使用@ModelAttribute注解参数。
9.21 MethodArgumentConversionNotSupportedException
在解析一个方法参数时引发的异常,提供了到目标MethodParameter的访问方法。
9.22 MethodArgumentTypeMismatchException
在解析一个控制器方法参数时引发的异常,提供了到目标MethodParameter的访问方法。
web/method/support
9.23 CompositeUriComponentsContributor
UriComponentsContributor接口的实现类,包含了一列contributors,还封装了一个特定的ConversionService用来将方法参数值转化成字符串格式。
9.24 HandlerMethodArgumentResolver
参数解析器,主要用途:统一封装登录的用户信息;进行数据绑定,参数验证。Spring MVC处理入参靠的是HandlerMethodArgumentResolver这个接口,解析返回值靠的是HandlerMethodReturnValueHandler这个策略接口。
9.25 HandlerMethodArgumentResolverComposite
所有的参数解析器的链表,保存了springMVC提供的所有的参数解析器,采用职责链的模式来完成参数解析器的查找,并完成参数解析生成目标对象。
9.26 HandlerMethodReturnValueHandler
策略接口,用来对调用处理函数之后的返回值进行处理,总共就两个方法;
boolean supportsReturnType();
void handleReturnValue()
9.27 HandlerMethodReturnValueHandlerComposite
springMVC提供的所有的HandlerMethodReturnValueHandler集合,它定义了一个链表用于存储所有实现的HandlerMethodReturnValueHandler。
9.28 AsyncHandlerMethodReturnValueHandler
继承自HandlerMethodReturnValueHandler,支持异步模式。
9.29 InvocableHandlerMethod
InvocableHandlerMethod是对HandlerMethod的扩展,基于一组HandlerMethodArgumentResolver从请求上下文中解析出控制器方法的参数值,然后调用控制器方法。
9.30 ModelAndViewContainer
可以把它定义为ModelAndView上下文的容器,它承担着整个请求过程中的数据传递工作,保存着Model和View。记录HandlerMethodArgumentResolver和 HandlerMethodReturnValueHandler在处理Controller的handler方法时 使用的模型model和视图view相关信息.。
9.31 UriComponentsContributor
帮助构建一个UriComponents,通过查找一个方法参数和参数值,决定目标URL哪一部分需要更新。
十、web/multipart
multipart/form-data请求说明:
先看一个带multipart/form-data的请求报文。假设客户端发送内容构造,接受文件的网页程序位于 http://192.168.29.65/upload_file/UploadFile,我们要发送一个二进制文件、一个文本框表单项、一个密码框表单项。文件名为 E:\s ,其内容如下:(其中的XXX代表二进制数据,如 01 02 03)abbXXXccc 客户端应该向 192.168.29.65 发送如下内容:
POST /upload_file/UploadFile HTTP/1.1
Accept: text/plain, */*
Accept-Language: zh-cn
Host: 192.168.29.65:80
Content-Type:multipart/form-data;boundary=---------------------------7d33a816d302b6
User-Agent: Mozilla/4.0 (compatible; OpenOffice.org)
Content-Length: 424
Connection: Keep-Alive -----------------------------7d33a816d302b6
Content-Disposition:form-data;
name="userfile1";
filename="E:\s"Content-Type:
application/octet-stream abbXXXccc
-----------------------------7d33a816d302b6
Content-Disposition: form-data;
name="text1" foo
-----------------------------7d33a816d302b6
Content-Disposition: form-data;
name="password1" bar
—-----------------------------7d33a816d302b6—
注意这一行:
Content-Type: multipart/form-data; boundary=---------------------------7d33a816d302b6
根据 rfc1867,multipart/form-data是必须的。---------------------------7d33a816d302b6 是分隔符,分隔多个文件、表单项。 其中33a816d302b6 是即时生成的一个数字,用以确保整个分隔符不会在文件或表单项的内容中出现。前面的 ---------------------------7d 是 IE 特有的标志。
在最初的http协议中,没有文件上传功能。rfc1867为http协议添加了这个功能:multipart/form-data。客户端浏览器按照此规范将用户指定的文件发送到服务器。服务器端的网页程序(如php、asp、jsp)按照此规范解析出用户发送来的文件。
1、multipart/form-data的基础方式是post,也就是说通过post组合方式来实现的。
2、multipart/form-data于post方法的不同之处在于请求头和请求体。
3、multipart/form-data的请求头必须包含一个特殊的头信息:Content-Type,其值也必须为multipart/form-data,同时还需要规定一个内容分割用于分割请求提中多个post的内容,如文件内容和文本内容是需要分隔开来的,不然接收方就无法解析和还原这个文件了,具体的头信息如下:
Content-Type: multipart/form-data; boundary=${bound}
其中${bound} 是一个占位符,代表我们规定的分割符,可以自己任意规定,但为了避免和正常文本重复了,尽量要使用复杂一点的内容。如上例中的:--------------------7d33a816d302b6
4、multipart/form-data的请求体也是一个字符串,不过和post的请求提不同的是它的构造方式,post是简单的name=value键值连接,而multipart/form-data是添加了分隔符等内容的构造体。
10.1 MultipartFile
继承自InputStreamSource接口,表示在一个接收到的multipart请求中的上传文件。文件的内容要么存储在内存中,要么暂时存在磁盘中。如果有要求的话,不管采取方式,用户都需要将文件的内容拷贝到会话级别或者永久性的存储中。临时性的存储会在multipart请求处理完毕后进行清空。
10.2 MultipartFileResource
使MultipartFile适配org.springframework.core.io.Resource,以InputStream暴露文件内容,重写方法contentLength()和getFilename()。
10.3 MultipartRequest
这个接口定义了multipart请求的存取操作。该接口被MultipartHttpServletRequest继承。
10.4 MultipartHttpServletRequest
继承自HttpServletRequest、MultipartRequest。在servlet request中提供了额外的方法,专门用来处理multipart内容,允许存取上传的文件。
10.5 MultipartResolver
MultipartResolver 用于处理文件上传,当收到请求时 DispatcherServlet 的 checkMultipart() 方法会调用 MultipartResolver 的 isMultipart() 方法判断请求中是否包含文件。如果请求数据中包含文件,则调用 MultipartResolver 的 resolveMultipart() 方法对请求的数据进行解析,然后将文件数据解析成 MultipartFile 并封装在 MultipartHttpServletRequest (继承了 HttpServletRequest)对象中,最后传递给 Controller,在 MultipartResolver 接口中有如下方法:
boolean isMultipart(HttpServletRequest request); // 是否是 multipart
MultipartHttpServletRequest resolveMultipart(HttpServletRequest request); // 解析请求
void cleanupMultipart(MultipartHttpServletRequest request);
10.6 MultipartException
multipart解析失败时抛出的异常。
10.7 MaxUploadSizeExceededException
继承自MultipartException,当上传的文件大小超过了最大限制时抛出的异常。
web/multipart/commons
10.8 CommonsFileUploadSupport
使用Apache的Commons FileUpload组件(1.2或者更高的版本)的multipart解析器的基类。
10.9 CommonsMultipartFile
MultipartFile接口的实现类,专为Apache Commons FileUpload。
10.10 CommonsMultipartResolver
使用 commons Fileupload 来处理 multipart 请求。在使用时要引入相应的 jar 包。
web/multipart/support
10.11 MultipartFilter
Servlet过滤器,在root WebApplicationContext容器中通过一个MultipartResolver来解析multipart请求。
10.12 MultipartResolutionDelegate
HandlerMethodArgumentResolver接口实现类的一个通用代理,用来解析MultipartFile和Part参数。
10.13 AbstractMultipartHttpServletRequest
MultipartHttpServletRequest接口实现类的抽象基类。提供了对预生成的MultipartFile实例的管理。
10.14 DefaultMultipartHttpServletRequest
MultipartHttpServletRequest接口的默认实现,提供了对预生成的参数值的管理。该类在CommonsMultipartResolver中使用。
10.15 RequestPartServletServerHttpRequest
ServerHttpRequest接口的实现类,用来存取multipart请求的一部分。如果使用MultipartResolver配置,该部分就通过MultipartFile进行存取。如果使用Servlet 3.0进行multipart处理,该部分就通过ServletRequest.getPart进行存取。
10.16 StandardMultipartHttpServletRequest
Spring MultipartHttpServletRequest的适配器,包装了一个ervlet 3.0 HttpServletRequest和它的Parts对象。
10.17 StandardServletMultipartResolver
基于 Servlet 3.0来处理 multipart 请求的,所以不需要引用其他 jar 包,但是必须使用支持 Servlet 3.0的容器才可以,以tomcat为例,从 Tomcat 7.0.x的版本开始就支持 Servlet 3.0了。
10.18 ByteArrayMultipartFileEditor
个性化的java.beans.PropertyEditor,用来将MultipartFiles转换成字节数组。
10.19 StringMultipartFileEditor
个性化的java.beans.PropertyEditor,用来将MultipartFiles转换成字符串。允许指定使用的字符集。
10.20 MissingServletRequestPartException
当通过名字进行寻找一个"multipart/form-data" 请求的一部分,但是查找不到时抛出异常。
十一、web/server
11.1 ServerWebExchange
ServerWebExchange名为服务网络交换器,是一个HTTP请求-响应交互的契约。提供对HTTP请求和响应的访问,并公开额外的服务器端处理相关属性和特性,如请求属性。存放着重要的请求-响应属性、请求实例和响应实例等等,有点像Context的角色。
11.2 ServerWebExchangeDecorator
ServerWebExchange装饰类,用于需要封装一个ServerWebExchange的类的基类,通过委托给包装实例预实现所有方法。
11.3 DefaultServerWebExchangeBuilder
ServerWebExchange的内部接口ServerWebExchange.Builder的实现类。
11.4 WebSession
使用服务器端会话的主要约定,提供了同HTTP请求间会话属性的访问。创建WebSession实例并不会自动开启一个会话。会话属性添加完毕后,调用WebSession.start()函数才开启一个会话,继而将会话id发送到客户端(比如通过cookie)。
Cookie机制和Session机制用来唯一标识一个用户,同时记录该用户的状态。cookie是存储子在客户端,而Session是存储在服务器端。
Session机制:采用的是在服务器端保持Http状态信息的方案。服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息。
当程序需要为某个客户端的请求创建一个session时,服务器首先检查这个客户端的请求里是否包含了一个session标识(即sessionId),如果已经包含一个sessionId则说明以前已经为此客户创建过session,服务器就按照session id把这个session检索出来使用。如果客户请求不包含sessionId,则为此客户创建一个session并且生成一个与此session相关联的sessionId,这个sessionId将在本次响应中返回给客户端保存。
11.5 WebFilter
使用拦截器链的方式来处理web请求的约定,主要被用来实现横切请求,比如安全。
11.6 WebFilterChain
过滤器链,使得链中的web过滤器转到下一个。
11.7 WebHandler
处理一个web请求。该接口定义了一个函数handle(ServerWebExchange exchange)。
11.8 WebExceptionHandler
对在执行处理ServerWebExchange时发生的异常进行处理。
11.9 ResponseStatusException
和指定的HTTP响应状态码相关的异常的基类。
11.10 ServerWebInputException
Spring web应用中遇到了响应状态码400(400 bad request,请求报文存在语法错误)抛出的异常。
11.11 MethodNotAllowedException
接收到响应状态码405(Method Not Allowed,请求行中指定的请求方法不能被用于请求相应的资源。)时抛出的异常。
11.12 ServerErrorException
HttpStatus为INTERNAL_SERVER_ERROR(服务器遇到了一个未曾预料的状况,导致了它无法完成对请求的处理。)时抛出的异常。
11.13 NotAcceptableStatusException
发生response status 406(Not Acceptable请求的资源的内容特性无法满足请求头中的条件,因而无法生成响应实体。)抛出的异常。
11.14 MediaTypeNotSupportedStatusException
发生response status 415(Unsupported Media Type,对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。)抛出的异常。
11.15 UnsupportedMediaTypeStatusException
发生response status 415(Unsupported Media Type,对于当前请求的方法和所请求的资源,请求中提交的实体并不是服务器中所支持的格式,因此请求被拒绝。)抛出的异常。
web/server/adapter
11.16 AbstractReactiveWebInitializer
继承自AbstractReactiveWebInitializer的类,可以在servlet容器中安装一个Spring Reactive Web Application。它通过将ServletHttpHandlerAdapter实例作为一个servlet安装到servler容器中。
11.17 DefaultServerWebExchange
ServerWebExchange接口的默认实现类。
11.18 ForwardedHeaderTransformer
处理HTTP头部,包括提取和移除某些头部键值对,或者只移除。
11.19 HttpWebHandlerAdapter
WebHandler的适配器。默认情况下创建和配置一个DefaultServerWebExchange,然后调用目标WebHandler。
11.20 WebHttpHandlerBuilder
此构建器有两个用途:
一是用来组装由目标WebHandler组成的处理链,使用一系列的WebFilters来装饰,更进一步的装饰使用一系列的WebExceptionHandlers。
二是借助HttpWebHandlerAdapter适配器使生成的处理器链适配一个HTTPHandler。
web/server/handler
11.21 DefaultWebFilterChain
WebFilterChain接口的默认实现,该类的每一个实例都表示链中的一个对象,构造器DefaultWebFilterChain(WebHandler, List)初始化了整个链,并执行链中第一个对象。
11.22 ExceptionHandlingWebHandler
WebHandler装饰器,调用一个或者多个WebExceptionHandlers。
11.23 FilteringWebHandler
通过WebFilter进行过滤处理的类,类似于Servlet中的Filter。
11.24 ResponseStatusExceptionHandler
通过设置响应的状态码来处理ResponseStatusException类型的异常。
11.25 WebHandlerDecorator
WebHandler的装饰器,利用装饰模式实现相关功能的扩展。
web/server/i18n
11.26 LocaleContextResolver
springMVC给我们提供了国际化支持,简单来说就是设置整个系统的运行语言,然后根据系统的运行语言来展示对应语言的页面,一般我们称之为多语言。springMVC国际化机制就是可以设置整个系统的运行语言。
LocaleContext该接口决定当前真正的Locale。
LocaleContextResolver:该接口用于解析基于web的local contex,允许通过request决定这个local context或者通过HTTP exchange来修改这个local contex。
11.27 AcceptHeaderLocaleContextResolver
LocaleContextResolver接口的实现类,解析器检查HTTP request中携带的"Accept-Language" 请求头,通常该请求头字段中包含了客户端地区信息。(这个地区信息由客户端浏览器发送,在客户端的操作系统中体系)。该解析器不支持设置LocalContext,
11.28 FixedLocaleContextResolver
LocaleContextResolver接口的实现类,一直使用固定的Local,不支持改变Local。默认的为JVM的默认local。
web/server/session
11.29 WebSessionIdResolver
WebSessionIdResolver定义了session id解析策略的契约。允许通过请求解析session id,并通过响应来发送session id或者终止会话。包含三个方法:
resolveSessionIds(ServerWebExchange exchange):解析与当前请求相关联的sessionId。sessionId可能来自Cookie或请求头。
setSessionId(ServerWebExchange exchange, String sessionId):将给定的sessionId发送给客户端。这个方法是在创建一个新session时被调用,并告知客户端新sessionId是什么。
expireSession(ServerWebExchange exchange):指示客户端结束当前session。当session无效时调用此方法,并应通知客户端sessionId不再有效。比如,它可能删除一个包含sessionId的Cookie,或者设置一个HTTP响应头,其值为空就表示客户端不再提交sessionId。
11.30 CookieWebSessionIdResolver
基于Cookie的WebSessionIdResolver。
11.31 HeaderWebSessionIdResolver
WebSessionIdResolver接口的实现类,通过从请求头header中解析出sessionId。
11.32 WebSessionManager
WebSession管理器,为HTTP request提供了访问WebSession的方法。该接口定义了一个方法getSession(),为一个给定的ServerWebExchange返回WebSession。
11.33 DefaultWebSessionManager
实现了WebSessionManager接口,主要定义了session的创建,启动,暂停与cookie的关联的定义。
11.34 WebSessionStore
会话存储接口,为WebSession持久化保存的策略接口。包含4个函数:
1、createWebSession()创建一个新的WebSession,该函数仅是创建一个会话实例,会话的启动通过WebSession#start()函数,持久化通过WebSession#save()函数。
2、retrieveSession(String sessionId);根据给定的sessionId返回相应的WebSession。
3、removeSession(String sessionId);删除指定sessionId的WebSession。
4、updateLastAccessTime(WebSession webSession):更新webSession的时间戳为当前时间。
11.35 InMemoryWebSessionStore
WebSessionStore接口的默认实现,采用map集合的方式来存储WebSession实例。
十二、web/util
12.1 ContentCachingRequestWrapper
把请求内容缓存起来的代理类。servlet的request body一旦流被读取了,就无法再次消费了,通过这个类能够解决HttpServletRequest inputStream只能读取一次的问题(request.getInputStream())。它使用一个字段:cachedContent来缓存body体里面的内容。
12.2 ContentCachingResponseWrapper
把响应内容缓存起来的代理类。缓存所有要写入getOutputStream()和getWriter()中的内容,允许该内容通过函数getContentAsByteArray()获得。
12.3 HtmlCharacterEntityDecoder
帮助类,通过使用实体字符(the referred character)来替换字符实体编码(character entity references)进行HTML字符串的解码操作。
12.4 HtmlCharacterEntityReferences
表示在HTML4.0标准中定义的一系列字符实体编码。完整的描述在https://www.w3.org/TR/html4/charset.html中。
12.5 HtmlUtils
很多时候,由于特殊字符的原因,会造成用户输入的信息反馈到页面上时会显示成乱码,造成页面排版混乱;另外,黑客经常利用特殊字符对网站进行xss跨站攻击,所以我们需要对页面上提交的特殊字符进行html转码。
转换为HTML转义字符表示、转换为数据转义表示、转换为十六进制数据转义表示。
12.6 JavaScriptUtils
基于JavaScript 1.5 recommendation对JavaScript进行转义。
12.7 WebUtils
WebUtils:该工具类主要用于Web应用程序,供各种框架使用。主要方法如下:
1、setWebAppRootSystemProperty:表示保存系统根路径的key-value
2、removeWebAppRootSystemProperty:表示移除系统根路径的key-value。
3、getDefaultHtmlEscape:看web.xml中的defaultHtmlEscape的值是否设置为true。
4、getTempDir:返回由当前servlet容器提供的 当前Web应用程序的临时目录。
5、getRealPath:返回由servlet容器提供的,Web应用程序中给定路径的实际路径。
6、getSessionId:返回指定的request的session id。
7、get/setSessionAttribute:根据当前的request和session attributes的name得到/设置session attributes的值。
8、getNativeRequest:返回指定类型的合适的请求对象,如果可用,会unwrapping给定的request请求。
9、getNativeResponse:返回指定类型的response对象。
10、isIncludeRequest:判断请求是否是一个包含(Include)请求,即不是从外部进入的*Http请求。
11、getCookie:获取制定名字的cookie。
12、getParametersStartingWith:返回包含具有给定前缀的所有参数的map。将单个值映射为String,多个值映射到String数组。
12.8 ServletContextPropertyUtils
用来解析文本中的占位符,常在文件路径中使用。
12.9 TagUtils
jsp标签的工具支持类。
12.10 UriUtils
处理uri里特殊字符的编码。
12.11 HttpSessionMutexListener
HttpSessionListener接口实现类,该Servlet HTTP 会话监听器会在一个Http会话创建的时候暴露会话的互斥锁。该监听器在web.xml中注册。
12.12 IntrospectorCleanupListener
1、此监听器主要用于解决java.beans.Introspector导致的内存泄漏的问题。
2、此监听器应该配置在web.xml中与Spring相关监听器中的第一个位置(也要在ContextLoaderListener的前面)。
3、JDK中的java.beans.Introspector类的用途是发现Java类是否符合JavaBean规范,如果有的框架或程序用到了Introspector类,那么就会启用一个系统级别的缓存,此缓存会存放一些曾加载并分析过的JavaBean的引用。当Web服务器关闭时,由于此缓存中存放着这些JavaBean的引用,所以垃圾回收器无法回收Web容器中的JavaBean对象,最后导致 内存变大。
而org.springframework.web.util.IntrospectorCleanupListener就是专门用来处理Introspector内存泄漏问题的辅助类。IntrospectorCleanupListener会在Web服务器停止时清理Introspector缓存,使那些Javabean能被垃圾回收器正确回收。Spring自身不会出现这种问题,因为Spring在加载并分析完一个类之后会马上刷新JavaBeans Introspector缓存,这就保证Spring中不会出现这种内存泄漏的问题。但有些程序和框架在使用了JavaBeans Introspector之后,没有进行清理工作(如 Quartz,Struts),最后导致内存泄漏。
12.13 WebAppRootListener
这个listener的作用就是监听web.xml中的配置param-name为webAppRootKey的值:
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>myroot</param-value>
</context-param>
然后配置这个监听器:
<listener>
<listener-class>org.springframework.web.util.WebAppRootListener</listener-class>
</listener>
作用:它会在ServletContext上下文初始化的时候,首先获取根传递进来的servletContext得到物理路径,String path=servletContext.getRealPath(""/"");然后找到context-param的webAooRootKey对应的param-value,把param-value的值作为key,上面配置的是""myroot""。
接着执行System.setProperty(""myroot"",path)。这样在web中任意地方就可以使用System.getProperty(""myroot"")来获取系统的绝对路径。
12.14 UriBuilder
URIBuilder主要用于构造URI,URI(Uniform Resource Identifier)即通一资源标志符,表示的是web上每一种可用的资源,如 HTML文档、图像、视频片段、程序等都由一个URI进行定位的。URL是URI的一个子集,它是Uniform Resource Locator的缩写,译为"统一资源定位符"。
12.15 UriBuilderFactory
用来创建UriBuilder实例。
12.16 DefaultUriBuilderFactory
UriBuilderFactory接口的实现类。依靠UriComponentsBuilder来实际创建一个URI。
12.17 UriComponents
表示一系列的不可改变的URI组件,将组件类型映射到字符串值。包含了所有组件的getters方法。实际上,同java.net.URI类似,不过拥有更强的编码选择,支持URI template变量。
12.18 OpaqueUriComponents
拓展自UriComponents,支持opaque URIs。
12.19 HierarchicalUriComponents
拓展自UriComponents,支持hierarchical URIs。
12.20 UriComponentsBuilder
Spring MVC 提供了一种机制,可以构造和编码URI – 使用UriComponentsBuilder和UriComponents。这样我们不再自己去拼接了,提高了正确性。它可以细粒度的控制URI的各个要素,如构建、扩展模板变量以及编码。
12.21 UriTemplate
用于处理格式化Uri模板。
12.22 UriTemplateHandler
定义了用来拓展URI模板类的方法。
12.23 AbstractUriTemplateHandler
UriTemplateHandler接口实现类的抽象基类。提供了setBaseUrl和setDefaultUriVariables方法,在子类中不管是URI模板的拓展还是编码机制都是密切相关的。
12.24 DefaultUriTemplateHandler
UriTemplateHandler接口的默认实现,使用UriComponentsBuilder来扩展和编码uri的。
12.25 UrlPathHelper
Spring用来处理URL的工具类,位于包org.springframework.web.util内。它帮助Spring MVC处理URL相关的各种难题。
12.26 CookieGenerator
生成Cookie。一般在CAS单点登录里用得较多。现在都用JWT了,就用得较少了。CAS (Central Authentication Server) 是 Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法。
Json web token (JWT),是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。该token被设计为紧凑且安全的,特别适用于分布式站点的单点登录(SSO)场景。
12.27 NestedServletException
继承自ServletException,从message和stacktrace角度来说,是在root处引发的异常,就像NestedChecked/RuntimeException。
web/util/pattern
12.28 SubSequence
用来返回一个数组的一个部分,当要把一个数据的子集传给另外一个函数但是不希望创建一个新的字符串对象时有用。
12.29 PathPattern
表示一个解析过的路径模式。包含一系列的路径元素用来快速匹配。
12.30 PathPatternRouteMatcher
RouteMatcher接口实现类,属性中包含了一个PathPatternParser对象,该类使用PathContainer和PathContainer表示route和patterns。
12.31 PathPatternParser
解析URI path patterns产生PathPattern实例对象,从而匹配request请求。
12.32 InternalPathPatternParser
解析URI template patterns。它把path pattern分解成许多PathElements,这些PathElements以链表形式组织。这些实例可重复使用,但是是非线程安全的。
12.33 PatternParseException
解析pattern时发生问题时抛出的异常。
12.34 PathElement
由抽象语法树节点创建,用来表示一个路径模式的通用超类。
12.35 LiteralPathElement
一个文字的路径元素。在'/foo/bar/goo'模式中,有三个文件的路径元素:'foo', 'bar'和 'goo'。
12.36 RegexPathElement
正则表达式的路径元素。用来表示复杂的路径元素。比如在'/foo/*_*/*_{foobar}' 中, *_* 和*_{foobar}都是正则表达式的路径元素。
12.37 SeparatorPathElement
路径分隔符元素,在模式'/foo/bar'总,两次出现的'/'可以使用SeparatorPathElement类进行表示(如果默认的分隔符是'/')。
12.38 CaptureVariablePathElement
路径中某一块是个变量,那么这个变量元素可以使用CaptureVariablePathElement表示。比如在'/foo/{bar}/goo' 中,{bar}就可以用该类表示。
12.39 WildcardPathElement
通配符路径元素。在'/foo/*/goo'中,这个*就可以用WildcardPathElement来表示。在整个路径上(如上例),至少要匹配一个字符,但是在一个路径的的末尾(如linux*),可以匹配0个字符。
12.40 SingleCharWildcardedPathElement
一个文字路径元素,该元素包括一个或多个通配符'?'(一个?通配符代替一个字符)。
12.41 CaptureTheRestPathElement
一个路径元素,表示捕获路径的其余部分,在'/foo/{*foobar}' 中/{*foobar}就可以用CaptureTheRestPathElement表示。
12.42 WildcardTheRestPathElement
一个路径元素,表示通配路径的其余部分。在'/foo/**'中/**就可以用WildcardTheRestPathElement来表示。
本文参考了博客园、****部分文献。
拓展阅读:
Spring框架之beans源码完全解析(https://www.cnblogs.com/xxkj/p/13929565.html)
Spring框架之AOP源码完全解析(https://www.cnblogs.com/xxkj/p/14094203.html)
Spring框架之jms源码完全解析(https://www.cnblogs.com/xxkj/p/14137694.html)
Spring框架之spring-web http源码完全解析(https://www.cnblogs.com/xxkj/p/14176911.html)
博众家之所长,集群英之荟萃。遴选各IT领域精品雄文!
欢迎关注“IT架构精选”