Spring-web

spring-web,spring-webmvc模块笔记,这块的类非常多,采用包划分对主要类&接口进行说明
Http部分 常用的常量和枚举
MediaType,HttpStatus,HttpHeaders,RequestMethod(有非常常用的key)
常见的接口
ClientHttpRequestFactory:请求对象生成工厂.常见的有HttpComponentsClientHttpRequestFactory,封装HttpClient对象
ClientHttpRequest:请求对象.可以执行请求方法,返回响应对象
ClientHttpResponse:响应对象.对于HttpComponentsClientHttpResponse而言就是封装HttpResponse
InterceptingClientHttpRequest-这里引入请求拦截器采用iterator来实现的责任链模式,这种实现还是第一次见,和i++的套路一样
HttpMessageConverterExtractor:消息转换提取器.类型转换
HttpMessageConverter:这个接口非常重要.它是实际的Java对象+MediaType与Http消息(请求->参数读取,响应->返回值写入)之间的转换,如MappingJackson2HttpMessageConverter
HttpEntity:表示一个Http实体对象,含有HttpHeaders信息和返回的body信息.后面分为RequestEntity和ResponseEntity
RestTemplate:通过api编程式发起http请求.实现部分通过RequestCallback构造请求回调,处理头信息和参数转换.返回时同理,它引入请求工厂和响应消息提取器帮助处理
remoting-httpinvoker HttpInvokerRequestExecutor:请求执行器.默认采用jdk的http发送,可以换成HttpComponentsHttpInvokerRequestExecutor使用apache的
HttpInvokerProxyFactoryBean:客户端代理.配置url,本地接口代理,调用请求执行器获取执行结果
HttpInvokerServiceExporter:服务端执行器.配置实际执行代理对象,序列化和反序列化返回
web包 SpringServletContainerInitializer:servlet3.0支持的容器初始化调用方式,spring将会对jar包中所有的WebApplicationInitializer类进行初始化
WebApplicationInitializer:内部的容器初始化回调的接口
HttpRequestHandler:主要是配合HttpRequestHandlerAdapter进行转换映射调用.可以比较通用的处理request和response,框架内使用较多
RequestAttributes:定义了request的基本属性及操作.使用较多的是ServletRequestAttributes
RequestScope/SessionScope:继承AbstractRequestAttributesScope,将资源绑定到request中.每次请求进来后通过RequestContextHolder获取
context WebApplicationContext:web容器的顶层定义.它继承原ApplicationContext
ConfigurableWebApplicationContext:可配置的WebApplicationContext接口定义
ConfigurableWebEnvironment:定义web环境.主要为将ServletContext和ServletConfig内容加载到环境中,一般实现为StandardServletEnvironment
ServletContextScope:与ServletContext对象绑定参数
StandardServletEnvironment:将ServletConfigPropertySource与ServletContextPropertySource对应的配置参数注册到环境对象中
AbstractContextLoaderInitializer:将ContextLoaderListener绑定到ServletContext
拓展容器类 AbstractRefreshableWebApplicationContext:web容器的基类.在postProcessBeanFactory阶段进行了初始化,包括ServletContextAware,ServletConfigAware的支持,web中scope的支持,ServletRequest,ServletResponse的属性注入支持,将ServletContext,ServletConfig加入容器等对应的web调整
AnnotationConfigWebApplicationContext:重写loadBeanDefinitions方法.载入AnnotatedBeanDefinitionReader对象,将处理注解需要的配置类注册到容器
XmlWebApplicationContext:重写loadBeanDefinitions方法.载入XmlBeanDefinitionReader对象,以xml的形式直接解析给定的资源集合
GenericWebApplicationContext:基本web应用,包含ServletContext对象的Aware提供,web相关作用域注册,主题支持
Listener相关 ContextLoaderListener:容器初始化后加载context对象并刷新,绑定context对象到容器中(默认加载的是XmlWebApplicationContext)
ContextCleanupListener:关闭容器时.对容器的属性中以”org.springframework.”开头的属性检查是否为DisposableBean,符合条件则调用destroy()方法
RequestContextListener:实现了ServletRequestListener,当有请求进入时将request对象绑定到RequestContextHolder中
ServletRequestHandledEvent:当请求完成后会推送的事件
cors origin不支持ant风格 表示全部否则必须精准匹配域名,比如:http://domain1.com
CorsProcessor:DefaultCorsProcessor对跨域请求的是否允许判定,以及响应头信息
CorsConfiguration:跨域配置.如允许的origin/method等
CorsConfigurationSource:管理url对应的CorsConfiguration
CorsRegistration:标记了url和对应的CorsConfiguration配置
CorsRegistry:提供了管理一组CorsRegistration的能力
filter GenericFilterBean:实现Filter默认的init方法,尝试将过滤器初始化的参数设置到当前对象属性中.通过BeanWrapper形式设值的,可以参考下
OncePerRequestFilter:保证一次请求只执行一次过滤器.其通过在request中增加FilterName属性进而判断,还有默认的不过滤异步,不过滤已产生错误行为.这是一个很好的基类,基本上所有的Filter都继承此基类.
CommonsRequestLoggingFilter:在拦截器执行前和执行后进行日志输出
CharacterEncodingFilter:字符编码设值过滤器.在执行前在request或response调用setCharacterEncoding(encoding)方法
CorsFilter:跨域过滤器处理.判断是否跨域请求.进行判定处理,主要依托CorsProcessor和CorsConfigurationSource类
HiddenHttpMethodFilter:在post请求中参数(默认_method)的值转为request.getMethod方法返回的值,用于有些请求中的方法指定
HttpPutFormContentFilter:支持PUT和PATCH请求的表单提交(默认情况下只支持GET和POST的表单)
RelativeRedirectFilter:通过RelativeRedirectResponseWrapper包装原Response对象,重写默认的sendRedirect重定向方法改为相对路径重定向
RequestContextFilter:主要将request对象绑定到RequestContextHolder中,方便后续直接获取
MultipartFilter:判断当前content-type为”multipart/*”的多文件类型,那么将request转为MultipartHttpServletRequest
method ControllerAdviceBean:将@ControllerAdvice注解转换为类对象操作
HandlerMethodArgumentResolver:参数解析器 对进行注解/指定类型的参数做转换
HandlerMethodReturnValueHandler:方法返回处理器
ModelAttributeMethodProcessor:默认非简单类型的处理转换.将表单数据读取通过DataBinder设值到参数对象,默认表单提交的参数转换器
RequestResponseBodyMethodProcessor:将@ResponseBody注解的参数从body体读取换成对应类型的对象以及支持 @ResponseBody注解的返回值返回json,实际上通过HttpMessageConverter进行的转换,ReturnValueHandler更多是处理header信息设置,具体的转换还是委托出去通过转换器处理

对参数和返回值做处理的2个常见处理器就是ModelAttributeMethodProcessor和RequestResponseBodyMethodProcessor
WebDataBinderFactory:创建DataBinder的工厂
DataBinder:进行数据绑定,转换和验证的聚合类.简单来看就是通过k-v的形式进行设值,并且将key对应value的对应属性类型进行转换处理
multipart MultipartFile: 上传文件的定义.主要实现为StandardMultipartFile
MultipartRequest:定义了Request操作获取MultipartFile的接口
MultipartHttpServletRequest:多文件上传时request会被转为此接口定义,它继承了MultipartRequest接口.
StandardMultipartHttpServletRequest:servlet3.0的标准实现.主要将javax.servlet.http.Part对象转为StandardMultipartFile对象
MultipartResolver:判断当前Request是否为多文件请求,转换request到MultipartHttpServletRequest.一般实现为StandardServletMultipartResolver
必须配合MultipartFilter过滤器使用,可以配合RequestPartMethodArgumentResolver参数解析支持@RequestPart注解
util DefaultUriBuilderFactory:提供uri的基本转换,编码,参数设置.
ContentCachingRequestWrapper:缓存request的内容,通过getContentAsByteArray方法可以多次获取
ContentCachingResponseWrapper:缓存response的响应内容,通过getContentAsByteArray方法可以多次获取,最后可以通过copyBodyToResponse响应
webmvc FrameworkServlet:主要定义初始化流程方法(initWebApplicationContext),以及HttpServlet的所有请求方法统一转到processRequest让子类doService处理,在顶层进行了Request和LocaleContext的线程绑定
这里详细说下DispatcherServlet核心转发流程部分.
初始化包含:
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
这里的初始化很多都是直接指定到"beanName+类型"也就是beanName不对的话也不会成功,比如MultipartResolver的beanName就必须是multipartResolver
主要执行流程:
入口请求都会到doService,它先把自己流程中使用到的Bean通过request属性暴露出去,然后执行核心转发接口doDispatch,
先检查是否为multipartRequest,如果是的话,通过multipartResolver把request换为MultipartHttpServletRequest
通过初始化的HandlerMapping列表依次进行getHandler来获取本次uri可以支持的HandlerExecutionChain(常见RequestMappingHandlerMapping)
继续通过初始化的HandlerAdapter列表进行support检查handler以找到对应的HandlerAdapter.
HandlerExecutionChain中已经初始化过了拦截器,此时开始执行前置拦截器
然后通过HandlerAdapter开始进行实际调用(常见RequestMappingHandlerAdapter)
这里举例RequestMappingHandlerAdapter#invokeHandlerMethod流程1@InitBinder解析解析执行类和@ControllerAdvice注解类的@InitBinder注解方法. 通过使用统一的WebDataBinderFactory在初始化DataBinder时将所有参数调用@InitBinder注解的方法在参数中传入DataBinder对象,让方法可以调整所有的参数转换和赋值2@ModelAttribute解析解析执行类和@ControllerAdvice注解类的@ModelAttribute注解方法.在执行目标方法前,先调用所有的@ModelAttribute注解方法3执行目标方法并返回生成ServletInvocableHandlerMethod对象来执行目标方法.将参数一一通过参数解析器转换,然后调用方法,最后如果需要的话对返回值进行转换处理

然后执行后置拦截器,最后进行结果处理
结果处理流程-如果有异常,那么通过之前初始化的HandlerExceptionResolver列表获取可以解析此异常的方法,并调用,获取返回值(通常无需返回值,直接通过response响应)替换原返回值,将获得的返回值ModelAndView进行处理,主要为通过之前初始化的ViewResolver列表获取View对象,然后调用将之前全流程组装的Model对象和request,response一起传入渲染方法render中进行响应处理(比如jsp,html页面,静态资源等)
Handle映射处理器 HandlerMapping: 映射处理器顶层接口.处理url->handler的关系,以及url->HandlerInterceptor的关系
AbstractHandlerMapping:定义getHandler的基本流程,委托子类获取Handler对象,添加符合条件的过滤器到执行链中,生成HandlerExecutionChain返回
AbstractHandlerMethodMapping:定义了getHandlerInternal基本流程,进行url匹配HandlerMethod,如果有多于1个HandlerMethod被匹配,抛出错误信息,否则设置request的attribute信息将HandlerMapping接口中的几个属性暴露出来,最后返回HandlerMethod.同时它也实现了Handler和Method的收集和url映射规则.它实现了InitializingBean,在初始化时调用子类判定bean和method是否需要映射,如果需要将映射信息保存到MappingRegistry内部类中
RequestMappingInfoHandlerMapping:为Handler引入具化类型RequestMappingInfo,同时实现部分父类抽象方法
RequestMappingHandlerMapping:引入@Controller和@RequestMapping注解的实现.实现父类需要具体判断的抽象方法
BeanNameUrlHandlerMapping:BeanName以”/“开头的直接当做url注册为处理,不过需要注意bean要实现Controller接口,可以选择继承AbstractController
其他关联类 HandlerExecutionChain:保存handler对象(这里的handler对象会被对应的XXAdapter进一步处理),控制当次请求过滤器链HandlerInterceptor的访问
HandlerMethod:保存Handler和Method的上下文和提供便捷操作方法
InvocableHandlerMethod:提供了请求参数转换和调用方法的功能
ServletInvocableHandlerMethod:增加了对返回值的处理转换能力
HandlerMethodArgumentResolver:参数解析器 一般情况通过HandlerMethodArgumentResolverComposite包装组合引用
HandlerMethodReturnValueHandler:返回值处理器 一般情况通过HandlerMethodReturnValueHandlerComposite包装组合引用
Handle适配器-适配转换Handler的调用处理
HandlerAdapter:接过HandlerMapping解析请求得到的handler对象.更精确的定位到能够执行请求的方法包装类
HttpRequestHandlerAdapter:转换适配带HttpRequestHandler接口handle的方法调用
SimpleControllerHandlerAdapter:转换适配带Controller接口handle的方法调用
RequestMappingHandlerAdapter:对RequestMappingInfo这个Handler的具化处理.这是一个主要的映射处理类.初始化了默认的参数解析器,@InitBinder时调用的参数解析器,返回值参数解析器,支持了@ControllerAdvice注解类中@InitBinder方法的全局调用,@ModelAttribute注解的方法级调用和全局调用
DataBinder-包装对象的访问/转换/验证封装
ServletRequestDataBinder:在bind时支持将reqesut.getParameterNames中的属性绑定到类对象属性
ExtendedServletRequestDataBinder:将URI信息也一起绑定到对象属性中
WebDataBinderFactory: DataBinder工厂.其中InitBinderDataBinderFactory在创建DataBinder时将@InitBinder注解的方法均触发执行
method RequestBodyAdvice:允许在读取消息前后进行操作消息内容
ResponseBodyAdvice:允许在返回消息体前进行操作消息内容
RequestResponseBodyAdviceChain:持有一组RequestBodyAdvice和ResponseBodyAdvice.在RequestResponseBodyMethodProcessor对参数进行解析前后,触发所有的回调.
常见转换器转换器 AbstractJackson2HttpMessageConverter:Jackson转换的顶层接口
MappingJackson2HttpMessageConverter:通过ObjectMapper转换Json对象,用的非常多
MappingJackson2XmlHttpMessageConverter:通过ObjectMapper转换xml对象
AbstractJsonHttpMessageConverter:Json转换顶层接口
GsonHttpMessageConverter:通过Gson转换json对象
ByteArrayHttpMessageConverter:可以直接将body内容转为byte[]参数,也可以直接返回byte[]
FormHttpMessageConverter:表单提交内容可以转为MultiValueMap参数
resolver-常用的参数/返回值解析器 很多参数解析器的功能都是通过HttpMessageConverter来实现,他们自身实现具体一种MediaType数据获取方式,然后将具体的参数转换方法让转换器完成
以MethodArgumentResolver结尾一般代表方法参数解析
RequestPartMethodArgumentResolver:支持参数注解@RequestPart解析
RequestAttributeMethodArgumentResolver:支持参数注解@RequestAttribute解析
PathVariableMethodArgumentResolver:支持非Map参数类型的@PathVariable注解解析
PathVariableMapMethodArgumentResolver:支持Map参数类型的@PathVariable注解解析
ServletRequestMethodArgumentResolver:支持servlet的一些api参数解析.如:ServletRequest,MultipartRequest,InputStream
ServletResponseMethodArgumentResolver:支持servlet的一些api返回值解析.如:ServletResponse
SessionAttributeMethodArgumentResolver:支持参数注解@SessionAttribute解析
以ReturnValueHandler结尾一般代表返回值解析
HttpHeadersReturnValueHandler:支持返回类型HttpHeaders
ModelAndViewMethodReturnValueHandler:支持返回值类型ModelAndView
ViewMethodReturnValueHandler:支持View类型的返回值解析
ViewNameMethodReturnValueHandler:支持String类型的返回值当做viewName进行解析
以Processor结尾一般代表既有参数值解析也有返回值解析
HttpEntityMethodProcessor:支持参数和返回值为HttpEntity类型
RequestResponseBodyMethodProcessor:支持@RequestBody参数注解和@ResponseBody的返回值注解
MvcConfig配置 基本上xxRegistry都是管理一组配置项 xxConfigurer就是全局统一的配置项
InterceptorRegistry:拦截器注册表.管理一组InterceptorRegistration拦截器配置类,可以通过getInterceptor()方法得到MappedInterceptor对象
CorsRegistry:跨域注册表.同理.持有一组CorsRegistration,然后可以直接获取CorsConfiguration
WebMvcConfigurer:配置接口.子类实现后可以通过xxConfigurer和xxRegistry进行调整
WebMvcConfigurationSupport:@EnableWebMvc注解提供的默认配置 注意,它不是配置接口,它是持有一组WebMvcConfigurer的配置类对象,和默认配置
默认HandlerMapping有RequestMappingHandlerMapping,BeanNameUrlHandlerMapping以及SimpleUrlHandlerMapping(注册的有
viewControllerHandlerMapping(对应的handler为ParameterizableViewController)
resourceHandlerMapping(对应的handler为ResourceHttpRequestHandler)
defaultServletHandlerMapping(对应的handler为DefaultServletHttpRequestHandler))
默认的HandlerAdapter有RequestMappingHandlerAdapter,HttpRequestHandlerAdapter,SimpleControllerHandlerAdapter(必须有这些适配器,否则上面的各种Handler就没法起作用了)
默认的异常解析器组合异常解析器HandlerExceptionResolverComposite
其中最主要的为ExceptionHandlerExceptionResolver,其次还有ResponseStatusExceptionResolver和DefaultHandlerExceptionResolver这俩
可以配置很多WebMvcConfigurer的Bean,最后在WebMvcConfigurationSupport中会进行汇总回调配置
Mvc Controller:接口,处理Request到ModelAndView转换
UrlFilenameViewController:url解析后直接访问资源视图.可以简单的配置BeanName映射然后访问静态资源
ModelAndView:方便将Model和View一起操作.在它之前的mav信息都是操作ModelAndViewContainer对象
ViewResolver:视图解析器.通过viewName返回View对象.比较常见的是InternalResourceViewResolver(普通的jsp,html加载都是它)
View:视图.只有一个渲染接口,响应内容
Resource
通过SimpleUrlHandlerMapping将url规则与ResourceResolver建立关联,最后通过HttpRequestHandlerAdapter调用ResourceHttpRequestHandler
ResourceHttpRequestHandler :资源请求处理handler
ResourceResolver是指资源解析过滤器链,包含有
CachingResourceResolver:增加一层spring缓存
GzipResourceResolver:gzip打包
PathResourceResolver:根据uri进行资源访问
DefaultResourceResolverChain:便于通过责任链模式操作ResourceResolver列表
DefaultResourceTransformerChain:便于通过责任链模式操作ResourceTransformer列表
View
InternalResourceViewResolver:内部资源视图解析器.比较常用的视图解析器,可以配置前后缀方便代码简化,以前使用的非常多,现在前后端分离后几乎不使用了
InternalResourceView:内部资源视图.通过RequestDispatcher的include(request, response); 方法直接解析
spring-web中常见注解
@InitBinder:通过注解指定方法调整WebDataBinder对象(InitBinderDataBinderFactory).是整个流程所有参数都生效的
@ModelAttribute:支持在方法上设置,即可以调整Model对象属性(ModelFactory),也可以在参数标注,即为表单映射数据解析(ModelAttributeMethodProcessor).不过实际上默认的非简单类型都使用的这个参数解析器,实际参数上用的不多(参考这个)
@ExceptionHandler:标注方法可以处理的异常.配合@ControllerAdvice使用
@ControllerAdvice:注解内部使用@ExceptionHandler,@InitBinder,@ModelAttribute注解的方法应用到所有的@RequestMapping注解的方法.其中异常处理使用的最多
@CookieValue:将cookie里的值直接取到方法参数中(ServletCookieValueMethodArgumentResolver)
@CrossOrigin:跨域请求配置,支持类级和方法级(RequestMappingHandlerMapping#initCorsConfiguration)
@RequestMapping:用于将Web请求映射到请求处理类中的方法的注解(RequestMappingHandlerMapping)
@GetMapping,@PostMapping,@PutMapping,@DeleteMapping,@PatchMapping 都是@RequestMapping注解指定了http方法的组合注解
@MatrixVariable:便捷的提取指定格式参数(MatrixVariableMapMethodArgumentResolver,MatrixVariableMethodArgumentResolver)
@PathVariable:处理URI中参数的提取(PathVariableMethodArgumentResolver)
@RequestAttribute:类似request.getAttribute(key)一样获取Attribute中的值(RequestAttributeMethodArgumentResolver)
@RequestBody:处理body体内数据转换.一般情况是json数据(RequestResponseBodyMethodProcessor)
@ResponseBody:将controller的方法返回的对象通过适当的转换器转换为指定的格式之后,写入到response对象的body区,通常用来返回JSON数据或者是XML数据,需要注意的呢,在使用此注解之后不会再走视图处理器,而是直接将数据写入到输入流中,他的效果等同于通过response对象输出指定格式的数据。
@RequestHeader:提取Header信息(RequestHeaderMethodArgumentResolver)
@RequestParam:默认的处理简单的类型参数映射.主要有get请求和post的表单提交(RequestParamMethodArgumentResolver)
@RequestPart:接收文件类型(MultipartFile)或文件集合类型(比如List)可以指定文件名的注解,如果没有此注解将会使用参数名作为默认名称
@ResponseStatus:在对应方法内发生异常时,将会按照方法或异常类含有的该枚举值进行设值提示
@RestController:@Controller+@ResponseBody的组合注解
@RestControllerAdvice:@ControllerAdvice+@ResponseBody的组合注解
@SessionAttribute,@SessionAttributes:从session获取值
@EnableWebMvc:引入默认配置DelegatingWebMvcConfiguration
类型转换的对比 BeanWrapper、DataBinder、ConversionService、Formatter
BeanWrapper
BeanWrapper提供了对属性设置的支持。BeanWrapper通常不会被应用程序的代码直接使用,而是由DataBinder和BeanFactory使用。
BeanWrapper的名字已经部分暗示了它的工作方式:它包装一个bean以对其执行操作,比如设置和获取属性。
支持复杂对象路由,数组对象,map对象
内置PropertyEditor,PropertyEditor隶属于Java Bean规范。PropertyEditor只提供了String <-> Object的转换。
使用PropertyEditorRegistry,继承PropertyEditorRegistrySupport管理PropertyEditor
ConversionService
ConversionService及其相关一套类型转换机制是一套通用的类型转换SPI,相比PropertyEditor只提供String<->Object的转换,ConversionService能够提供任意Object<->Object的转换。
所以我们可以猜测,Spring为何要使用ConversionService替代PropertyEditor有三个原因:
1ConversionService功能更强大,支持的类型转换范围更广。
2ConverterFactory支持一整个class hierarchy的转换(也就是多态),PropertyEditor则不行。
3Java Bean这个规范最初是和Java GUI(Swing)一起诞生的,PropertyEditor接口里有大量和GUI相关的方法,显然已经过时了。顺便提一句,Java Bean和POJO不是一个概念,Java Bean不仅有setter、getter,还有一系列和Java GUI配套的东西。
DefaultConversionService支持配置任意的ConverterRegistry
Formatter
Formatter SPI是另外一套和PropertyEditor类似的,String<->Object的转换机制,但是有两个优点:
接口更干净,没有关于GUI的部分,只有print和parse两个方法。
基于注解,支持同一类型的属性根据不同的格式来做String<->Object的转换。比如日期类型,一个字段的格式是yyyy-MM-dd,另一个格式是yyyyMMdd,如果利用PropertyEditor是比较麻烦,但是在这里就可以利用@DateTimeFormat来达到这个效果。
Spring提供了DefaultFormattingConversionService来支持Formatter SPI,也就是说如果要使用Formatter SPI,依然可以利用ConversionService接口.这里采用适配器进行了转换
注意:Formatter SPI必须基于注解才可以使用,这点和ConversionService基于类型不同。
Formatter是PropertyEditor的另一种转换格式的补充
DataBinder
DataBinder主要提供了两个功能:
1利用BeanWrapper,给对象的属性设值
【Spring-web】2在设值的同时做Validation
Spring-web
文章图片
关系图

    推荐阅读