WebMvcConfigurationSupport是mvc的核心配置。开发spring,了解和掌握这个是必须的。

为了简约篇幅,本文把"WebMvcConfigurationSupport"缩写为wms。

本文主要关注围绕DispatcherServlet(分发者服务程序)发生的和wms有关的一些内容,不关注http请求在容器部分的机制和代码。

通过本文能够:

  1. 了解wms是做什么的
  2. 了解大体如何使用wms
  3. 作为了解和使用wms的一个简单参考

一、wms的介绍

1.原文注释

    This is the main class providing the configuration behind the MVC Java config.
    It is typically imported by adding @EnableWebMvc to anapplication @Configuration class.
    An alternative more advanced option is to extend directly from this class and override methods as necessary,
    remembering to add @Configuration to the subclass and @Bean to overridden @Bean methods.
    For more details see the javadoc of @EnableWebMvc.

This class registers the following HandlerMappings:
    •RequestMappingHandlerMapping ordered at 0 for mapping requests to annotated controller methods.
    •HandlerMapping ordered at 1 to map URL paths directly to view names.
    •BeanNameUrlHandlerMapping ordered at 2 to map URL paths to controller bean names.
    •RouterFunctionMapping  ordered at 3 to map router functions.
    •HandlerMapping ordered at Integer.MAX_VALUE-1 to serve static resource requests.
    •HandlerMapping ordered at Integer.MAX_VALUE to forward requests to the default servlet.

Registers these HandlerAdapters:
    •RequestMappingHandlerAdapter for processing requests with annotated controller methods.
    •HttpRequestHandlerAdapter for processing requests with HttpRequestHandlers.
    •SimpleControllerHandlerAdapter for processing requests with interface-based Controllers.
    •HandlerFunctionAdapter for processing requests with router functions.

Registers a HandlerExceptionResolverComposite with this chain ofexception resolvers:
    •ExceptionHandlerExceptionResolver for handling exceptions through org.springframework.web.bind.annotation.ExceptionHandler methods.
    •ResponseStatusExceptionResolver for exceptions annotated with org.springframework.web.bind.annotation.ResponseStatus.
    •DefaultHandlerExceptionResolver for resolving known Springexception types

Registers an AntPathMatcher and a UrlPathHelperto be used by:
    •the RequestMappingHandlerMapping,
    •the HandlerMapping for ViewControllers
    •and the HandlerMapping for serving resources
    Note that those beans can be configured with a PathMatchConfigurer.

Both the RequestMappingHandlerAdapter and the ExceptionHandlerExceptionResolver are configured with default instances of the following by default:
    •a ContentNegotiationManager
    •a Default FormattingConversionService
    •an org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean if a JSR-303 implementation is available on the classpath
    •a range of HttpMessageConverters depending on the third-partylibraries available on the classpath.

我们翻译下:

    wms是webMvc通过java代码方式配置的主类。
    典型地,可以通过给一个应用的配置类(带@Configuration)添加@EnableWebMvc注解,即可导入Mvc java 配置。
    另外一个更加高级的替代选项是继承本类,并根据需要重写一些方法,并记得为这个子类添加@Configuration注解,同时为那些重写@Bean方法添加@Bean注解。
    更多的内容,请参考@EnableWebMvc的java文档

    本类注册以下处理器映射:
    .RequestMappingHandlerMapping(RequestMapping处理器映射) ,顺序为0,用于映射带注解的控制器方法
    .HandlerMapping (处理器映射),顺序1,用于映射url路径和视图名称
    .BeanNameUrlHandlerMapping(bean名称处理器映射),顺序2,用于映射url路径到控制器bean名称
    .RouterFunctionMapping(路由器功能映射),顺序3,用于映射路由函数
    .HandlerMapping (处理器映射),顺序Integer.MAX_VALUE-1,用于处理静态资源请求
    .HandlerMapping (处理器映射),顺序Integer.MAX_VALUE,用于服务器内部重定向到一个默认的servlet

    注册这些处理器适配器:
    •RequestMappingHandlerAdapter(RequestMapping处理器适配器),用于处理到带注解的控制器方法请求
    •HttpRequestHandlerAdapter(http请求处理器适配器),用于处理 带HttpRequestHanders的请求
    •SimpleControllerHandlerAdapter(简单控制器处理器适配器),用于处理基于接口的控制的请求
    •HandlerFunctionAdapter(处理器功能适配器),用于处理带路由器功能的请求

    注册处理器异常解析复合器,该复合器带有一些异常处理器:    
    •ExceptionHandlerExceptionResolver(异常处理器异常解析器),用于处理org.springframework.web.bind.annotation.ExceptionHandler的异常
    •ResponseStatusExceptionResolver(响应状态异常解析器),用于处理org.springframework.web.bind.annotation.ResponseStatus异常
    •DefaultHandlerExceptionResolver(默认处理器异常解析器),用于处理已知的的spring异常类

    注册一个antPathMatcher和一个urlPathHelper,以便能够被以下对象使用:
    •RequestMappingHandlerMapping(RequestMapping处理器映射)
    •HandlerMapping for ViewControllers ,用于视图控制器的处理器映射
    •HandlerMapping for serving resources ,用于处理资源的处理器映射
    注意,以上这些bean可以通过PathMatchCOnfigurer配置。

    RequestMappingHandlerAdapter和ExceptionHandlerExceptionResolver都由以下对象的默认实例配置了:
    .ContentNegotiationManager(媒体类型管理器,用于侦测请求的媒体类型)
    .FormattingConversionService(格式转换服务)
    .org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean(bean验证器,如果类路径具有JSR-303的实现)
    .HttpMessageConverters(http消息转换器)。具体有几个转换器,需要看类路径的三方实现库的多寡

2.功能

如它的名称,即执行各种webMvc的配置,通过在其中定义大量的有关Bean(大约有25个左右),方便MVC的流程的特定环节从Bean工厂中获取这些bean,并利用这些Bean完成webMvc的大部分工作。

概括下,wms就是这些功能:

  • 注册处理器映射,以便把请求导向具体的控制器、控制器方法、视图、资源。注意,这些映射器的目的是做一个关系匹配
  • 注册处理器适配器,为具体的功能选择具体的处理程序。例如参数解析,消息转换等
  • 注册异常处理器
  • 注册路径映射解析有关类

总而言之,言而总之,wms就是告诉spring用于处理请求的有关工具,这些工具用于处理映射关系,解析参数,返回消息等等

一个完整的web请求和响应过程中需要执行的动作所使用的配置(程序、配置)基本都可以在wms中进行管理,记住这一点基本上算是对wms有所了解了

二、名词解析

需要记住和理解的名词非常多,只能挑本人关注的。

1.解释器/解决器

英文:Resolver

中文含义:问题解决者。  针对不同的场景,可以有很多的解释。在本文中,按照习惯,我们从用途进行翻译,大体翻译为解释器,转换器都可以。

2.拦截器

英文:interceptor

中文含义:进行拦截的人/物。在spring中,专门指拦截http请求的一段程序。和过滤器基本一样,没有什么本质上的区别。不过拦截器可以打断请求的过程,而过滤器主要做重定向(如果有必要)

3.控制器、参数、方法

控制器:controller,对应注解@Controller

参数:parameter,这里主要阐述的是控制器中方法的入参

方法:method,这里指控制器中的方法(有Request的方法)

我们日常spring编程主要针对这三者。

某种程度上,只要会复制粘贴+mvc你就可以说自己是一个java开发工程师了,是不是很容易啊?

4.返回值、消息

返回值:return value。控制器方法大部分情况下都有返回值,如果没有,那么spring也会给一个默认的响应

消息:message.这里指从客户端发送的请求消息或者是服务端返回给客户端的消息。这里我们主要关心ResponseBody注解。

5.Cors

英文:CORS(Cross-origin resource sharing)

中文:跨源资源共享

一般情况下,web服务器不允许跨源资源共享,但很多时候又有这个需求。所以需要指定什么资源可以被什么其它非同源请求访问。

6.资源和视图

资源:resource,spring通常指静态的数据(包括图片,脚本,文本,多媒体信息等等)

视图:view,spring指展示信息的页面

7.验证器

英文:validator,spring通常指用于校验特定参数的简单业务逻辑

8.格式化器和转换器

格式化器:formatter

转换器:converter

二者有相通之处,但基本一致,格式和转换基本即使你中有我,我中有你,密不可分。其作用,顾名思义,就是进行转化/格式化。 例如消息转换、属性转换等。

9.异常

具体略。

10.应用上下文和sevlet上下文

这两个太重要,因为WebMvcConfigurationSupport实现的很大一部分和应用上下文、服务器上下文有关。

  • ApplicationContext:应用上下文,属于spring自有的一个应用上下文,主要管理spring的bean。能够管理bean,绝对是spring的最核心能力之一。

包路径:org.springframework.context.ApplicationContext

  • ServletContext:服务器上下文,准确地说,通常地说,它指的是web服务器/容器的根上下文,容器通常为每个应用创建一个服务器上下文,保存应用和web相关的许多基本信息。

包路径:javax.servlet.ServletContext

我们开发的系统,某个方便面来说就是和两个东西关联:web+bean。web和bean有关的上下文就是 ServletContext,ApplicationContext。

11.媒体/媒介类型

英文:MediaType

包路径:org.springframework.http.MediaType

根据介绍,媒体/媒介类型实为MimeType的子类,spring仅仅对它做了一些包装,方便使用。

所以,根本上要理解MiME在http协议中的地位。

Mime的非常友好的介绍见这里:MIME 类型 - HTTP | MDN (mozilla.org)

或者看这里 MIME(多用途互联网邮件扩展类型)_百度百科 (baidu.com)

两个结合起来,就能够明白mime是什么东西。

如果有什么值得记的,就是为什么叫” mail extensions"(邮件扩展)。

邮件大概是互联网最早传递的数据信息,而且基本上是最重要的,所以开始命名的时候就这么叫了。但是现在iana(互联网号码分配机构)又慢慢要抛弃mime这个概念,改为mediaType(媒体类型)

很明显这么称呼是更加合理的,如果没有什么特别说明,“媒体类型”就是表示MINE或者上下文类型(context-type)

 12.请求映射处理器映射器(RequestMappingHandlerMapping)

注意这个前缀 RequestMapping(请求映射)本身是注解的名称(@RequestMapping)。

所以这个东西可以理解为RequestMapping注解的处理器映射器,大体作用是在注解和资源之间建立映射关系。

我们看下源码(默认的):

@Bean
@SuppressWarnings("deprecation")
public RequestMappingHandlerMapping requestMappingHandlerMapping(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) { RequestMappingHandlerMapping mapping = createRequestMappingHandlerMapping();
mapping.setOrder(0);
mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
mapping.setContentNegotiationManager(contentNegotiationManager);
mapping.setCorsConfigurations(getCorsConfigurations()); PathMatchConfigurer pathConfig = getPathMatchConfigurer();
if (pathConfig.getPatternParser() != null) {
mapping.setPatternParser(pathConfig.getPatternParser());
}
else {
mapping.setUrlPathHelper(pathConfig.getUrlPathHelperOrDefault());
mapping.setPathMatcher(pathConfig.getPathMatcherOrDefault()); Boolean useSuffixPatternMatch = pathConfig.isUseSuffixPatternMatch();
if (useSuffixPatternMatch != null) {
mapping.setUseSuffixPatternMatch(useSuffixPatternMatch);
}
Boolean useRegisteredSuffixPatternMatch = pathConfig.isUseRegisteredSuffixPatternMatch();
if (useRegisteredSuffixPatternMatch != null) {
mapping.setUseRegisteredSuffixPatternMatch(useRegisteredSuffixPatternMatch);
}
}
Boolean useTrailingSlashMatch = pathConfig.isUseTrailingSlashMatch();
if (useTrailingSlashMatch != null) {
mapping.setUseTrailingSlashMatch(useTrailingSlashMatch);
}
if (pathConfig.getPathPrefixes() != null) {
mapping.setPathPrefixes(pathConfig.getPathPrefixes());
} return mapping;
}

这个代码核心是创建一个RequestMapping的处理器映射器,这个映射器又包含了什么东西了?

  1. 添加默认的转换器和资源url管理器的拦截器
  2. 添加请求媒体类型管理器
  3. 添加了跨域请求配置
  4. 添加了路径匹配器,以及路径有关的一些其它程序

13.请求映射处理器适配器(RequestMappingHandlerAdapter)

RequestMapping注解处理器适配器。

看源码(默认):

@Bean
public RequestMappingHandlerAdapter requestMappingHandlerAdapter(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcValidator") Validator validator) {
RequestMappingHandlerAdapter adapter = createRequestMappingHandlerAdapter();
    adapter.setContentNegotiationManager(contentNegotiationManager);
    adapter.setMessageConverters(getMessageConverters());
    adapter.setWebBindingInitializer(getConfigurableWebBindingInitializer(conversionService, validator));
    adapter.setCustomArgumentResolvers(getArgumentResolvers());
    adapter.setCustomReturnValueHandlers(getReturnValueHandlers());

    if (jackson2Present) {
        adapter.setRequestBodyAdvice(Collections.singletonList(new JsonViewRequestBodyAdvice()));
        adapter.setResponseBodyAdvice(Collections.singletonList(new JsonViewResponseBodyAdvice()));
    }

    AsyncSupportConfigurer configurer = getAsyncSupportConfigurer();
    if (configurer.getTaskExecutor() != null) {
        adapter.setTaskExecutor(configurer.getTaskExecutor());
    }
    if (configurer.getTimeout() != null) {
        adapter.setAsyncRequestTimeout(configurer.getTimeout());
    }
    adapter.setCallableInterceptors(configurer.getCallableInterceptors());
    adapter.setDeferredResultInterceptors(configurer.getDeferredResultInterceptors());

    return adapter;
}
  1. 设置媒体类型管理器(和映射器一样,都必须了解请求的媒体类型)
  2. 设置消息转换器
  3. web绑定初始化器(和转换服务、验证器有关)
  4. 设置自定义参数解释器
  5. 设置自定义返回值处理器
  6. 添加jackson请求体RequestBody顾问(如果有jackson类)
  7. 添加jackson响应体ResponseBody顾问(如果有jackson类)
  8. 配置异步任务执行器,设置异步请求超时。如果有配置异步
  9. 配置异步的可调用拦截器
  10. 配置异步延时结果拦截器

把这个内容和RequestMappingHanlderMapping的内容对照下,我们就更能够理解二者的区别。

--------------------------------------------------------------------------------------------------------------------

  • 映射器:主管资源和路径有关的内容
  • 适配器:主管具体请求消息处理和返回消息

注:spring已经提供了消息处理器的默认实现JackSon.

RequestMappingHandlerAdapter和RequestMappingHandleMapping是DispatcherServlet(分发器)的主要处理内容。

以下是分发器属性的主要内容:

/** MultipartResolver used by this servlet. */
@Nullable
private MultipartResolver multipartResolver; /** LocaleResolver used by this servlet. */
@Nullable
private LocaleResolver localeResolver; /** ThemeResolver used by this servlet. */
@Nullable
private ThemeResolver themeResolver; /** List of HandlerMappings used by this servlet. */
@Nullable
private List<HandlerMapping> handlerMappings; /** List of HandlerAdapters used by this servlet. */
@Nullable
private List<HandlerAdapter> handlerAdapters; /** List of HandlerExceptionResolvers used by this servlet. */
@Nullable
private List<HandlerExceptionResolver> handlerExceptionResolvers; /** RequestToViewNameTranslator used by this servlet. */
@Nullable
private RequestToViewNameTranslator viewNameTranslator; /** FlashMapManager used by this servlet. */
@Nullable
private FlashMapManager flashMapManager; /** List of ViewResolvers used by this servlet. */
@Nullable
private List<ViewResolver> viewResolvers;

三、spring-mvc种http请求大概执行过程

这么多名词,其实本质上就是围绕http展开的,具体来说就是围绕spring的http实现来展开。

我们使用spring的主要目的就是为了web(http)应用。可以说,没有web,spring的存在的意义基本上就没有了。

利用ide提供的调试工具,最容易能够直观地了解一个http请求的大概执行过程。如果愿意,还可以详细到每一行代码。

下图是调试的时候,显示的调用链:

四、常用-配置拦截器

     如何配置拦截器,这个没有什么太多可说。

记住一点,现在不但spring自身实现功能的时候使用了很多的拦截器(这个在springCloud中很明显),就是一般的开发人员也喜欢()用大量的拦截器。

我们只能感激一点:现在电脑越来愉快了。

配置例子。

@Override
protected void addInterceptors(InterceptorRegistry registry) {
// 以下是启用 token认证的. 本例使用cookie认证的时候,请注释掉,避免无法完成测试
// 反过来,如果启用了token认证,那么过滤器验证就可以取消掉 ,或者取消 上文的 registrationBean()
registry.addInterceptor(new MyInterceptor()).addPathPatterns("/**").excludePathPatterns("*.js")
.excludePathPatterns("*.html").excludePathPatterns("*.css").excludePathPatterns("/login")
.excludePathPatterns("/logout").excludePathPatterns("/index").excludePathPatterns("/");
super.addInterceptors(registry);
}

五、常用-方法参数(输入)解析(请求)

spring已经有提供默认的以下几个注解的处理:@RequstBody,@RequestParam

但是当我们开发api的时候,常常有这样的需求:

  • 在过滤器或者拦截器拦截请求并获取有关参数
  • 在具体的控制方法中想获取请求的一些固定信息,例如登录用户信息,授权信息等等 。

5.1 例子-自定义参数注解

、 如果每个地方都写,有点麻烦,所以spring允许自定义的参数解析。

例子:

a.定义一个注解
@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface SessionAtrrAnnotation { }

b.继承并实现HandlerMethodArgumentResolver
public class LoginUserArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter parameter) {
return parameter.hasParameterAnnotation(SessionAtrrAnnotation.class);
} @Override
public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer,
NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
return webRequest.getNativeRequest(HttpServletRequest.class).getSession().getAttribute("userInfo");
} }

c.在wms中注册
@Override
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) {
resolvers.add(new LoginUserArgumentResolver());
} d.应用
@RequestMapping(value = "/deleteById")
@ResponseBody
public PublicReturn deleteById(@SessionAtrrAnnotation LoginUserInfo loginInfo) {
//TODO:删除用户
return null;
}

5.2 自定义特定数据类型解析

这种自定义类型,有两种情况:

a.解析非JSON媒体类型的参数

b.解析媒体类型为JSON的参数中某个属性

这个网络上有很多解决方案,例如:

SpringMVC自定义处理多种日期格式的格式转换器_二木成林的博客-CSDN博客_springmvc日期转换   -- 这个是解析非json媒体类型参数的

不过作者是比较传统的xml配置,如果是springboot,直接在wms中覆盖addFormatters即可。

fastjson序列化时间自定义格式_biangabiang的博客-CSDN博客_fastjson自定义序列化格式 --使用阿里巴巴的fastjson,不过记得先配置Http消息转换器为FastJson(覆盖wms中的configureMessageConverters)

这是因为fastjson允许针对不同类型使用不同的序列化程序。

5.3媒体类型为JSON,且使用JackSon处理特定类型

无论是JackSon还是FastJson的,它们都是实现了HttpMessageConverter接口。 标准一样,细节有所区别而已。

所以,如果使用默认的JackSon的时候,可以和网上常常提到的FASTjson一样的思路来解决问题。

有关内容可以看这个:Jackson Tutorial | Baeldung

然而比较简单的方式还是覆盖下configureMessageConverters,在其中定制化MappingJackson2HttpMessageConverter的各种属性。

例如网上有这样的例子:

@Bean
public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
Jackson2ObjectMapperBuilder builder = new Jackson2ObjectMapperBuilder().serializers(LOCAL_DATETIME_SERIALIZER)
.serializationInclusion(JsonInclude.Include.NON_NULL);
return new MappingJackson2HttpMessageConverter(builder.build());
}

如果仅仅是想自定义序列化或者反序列化器,那么使用注解即可:

@JsonSerialize(using = FamilyJSONSerializer.class)
public class Family {
private Integer id;
private String name;
private Date addTime;
private Date lastOptime;
private String batchNo;
}

FamilyJSONSerializer的代码如下:

package study.config.message;

import java.io.IOException;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider; import study.model.family.Family; public class FamilyJSONSerializer extends JsonSerializer<Family>{ @Override
public void serialize(Family value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
if (value==null) {
gen.writeString("{}");
return;
}
gen.writeString(value.toString());
} @Override
public Class<Family> handledType(){
return Family.class;
}
}

自定义消息的解析,通常不是那么迫切,只要知道大概即可。

没有必要耗费太多的时间研究,并重新做一个轮子。

六、常用-响应消息(http消息转换)配置(响应)

spring的设计是允许有多个http消息转换器,每个转换器对应不同的媒体类型。这些转换器只要实现HttpMessageConverter接口即可。

当然如果你自己自定义,也可以让一个转换器对应n种媒体类型,或者n个转换器对应一个媒体类型。

如果是这种情况,spring会采用一定的选择缺略,保证每个媒体类型都可以进行适当的转换。

网上太多了,不再详细说明了。常见的即使用fastJson--覆盖wms中的configureMessageConverters。

下面是jackson的例子:

@Override
protected void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add(new ByteArrayHttpMessageConverter());
converters.add(new StringHttpMessageConverter());
converters.add(new ResourceHttpMessageConverter());
converters.add(new ResourceRegionHttpMessageConverter());
MappingJackson2HttpMessageConverter jconverter = new MappingJackson2HttpMessageConverter();
ObjectMapper objectMapper=jconverter.getObjectMapper();
objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeString("");
}
});
DateFormat dateFormat=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
objectMapper.setDateFormat(dateFormat);
converters.add(jconverter);
}

主要两点:设置日期格式、null输出为"",节约前端编码工作量。

七、常用-配置视图和资源解释

例如:

   @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/**")
.addResourceLocations("classpath:/static/")
.addResourceLocations("classpath:/public/")
.addResourceLocations("classpath:/resources/")
.addResourceLocations("file:" + uploadPath);
} @Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/").setViewName("main/index");
registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
super.addViewControllers(registry);
}

八、小结

对于大部分的javaEE开发的工程师而言,都有必要理解webMvc的机制,以及wms的配置。

wms既简单又复杂,涉及到webMvc的方法面面,相关的源码非常之多,如要透彻了解其原理和机制只有一个方法:仔细阅读并做好笔记。

此外,建议在阅读本代码前,先掌握http请求的基本原理和流程。另外为了提高阅读和理解的效率,建议开启调试模式,逐步调试,就能够较快了解这里所涉及的有关知识。

我个人一直喜欢用这个方法。现在ide对于这个的支持非常好,无论是eclipse,idea还是netbean,似乎除了跟踪不到机器指令,任何东西都可以跟踪和窥探,强大到难以置信。

在调试过程中,可以发现代码是从web容器(或者服务器)开始执行的,并最好从org.springframework.web.servlet.DispatcherServlet开始,因为在此类之前的大部分属于容器的api。

Spring之WebMvcConfigurationSupport的更多相关文章

  1. HandlerMethodArgumentResolver 自定义使用

    HandlerMethodArgumentResolver 自定义使用 1.HandlerMethodArgumentResolver 的应用场景 ​ HandlerMethodArgumentRes ...

  2. Spring EnableWebMvc vs WebMvcConfigurationSupport

    EnableWebMvc vs WebMvcConfigurationSupport spring doc解释 WebMvcConfigurationSupport: This is the main ...

  3. Spring boot 梳理 -@SpringBootApplication、@EnableAutoConfiguration与(@EnableWebMVC、WebMvcConfigurationSupport,WebMvcConfigurer和WebMvcConfigurationAdapter)

    @EnableWebMvc=继承DelegatingWebMvcConfiguration=继承WebMvcConfigurationSupport 直接看源码,@EnableWebMvc实际上引入一 ...

  4. Spring 梳理 - JavaConfig、SPI、SCI、SpringSCI、WebApplicationInitializer、AbstractAnnotationConfigDispatcherServletInitializer、WebMvcConfigurationSupport

    总结1: SCI:Servlet容器(Tomcat)提供的初始化Servlet容器本身的接口,可替换web.xml SpringSCI:SpringServletContainerInitialize ...

  5. Spring Boot中只能有一个WebMvcConfigurationSupport配置类

    首先将结论写文章的最前面,一个项目中只能有一个继承WebMvcConfigurationSupport的@Configuration类(使用@EnableMvc效果相同),如果存在多个这样的类,只有一 ...

  6. spring boot 添加拦截器

    构建一个spring boot项目. 添加拦截器需要添加一个configuration @Configuration @ComponentScan(basePackageClasses = Appli ...

  7. Spring MVC中使用 Swagger2 构建Restful API

    1.Spring MVC配置文件中的配置 [java] view plain copy <!-- 设置使用注解的类所在的jar包,只加载controller类 --> <contex ...

  8. Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC

    内容列表: 启用MVC Java config 或 MVC XML namespace 修改已提供的配置 类型转换和格式化 校验 拦截器 内容协商 View Controllers View Reso ...

  9. Spring MVC对象转换说明

    在Spring MVC之前我们需要在Servlet里处理HttpServletRequest参数对象,但这个对象里的属性都是通用类型的对象(如字符串),处理起来很繁琐并且容易出错,而Spring MV ...

  10. Spring Boot 学习(2)

    文 by / 林本托 Tips 做一个终身学习的人. 源代码:github下的/code01/ch2. 配置 Web 应用程序 在上一章中,我们学习了如何创建一个基本的应用程序模板,并添加了一些基本功 ...

随机推荐

  1. dotnet OpenXML 利用合并表格单元格在 PPT 文档插入不可见的额外版权信息

    本文告诉大家如何利用 Office 对于 OpenXML 支持的特性,在 PPT 的表格里面,通过合并单元格存放一些额外的信息,这些信息对用户来说是不可见的,但是进行拷贝表格等的时候,可以保存此信息内 ...

  2. 5.prometheus监控--监控nginx

    1.监控程序环境准备 mkdir /data/docker-compose -p cd /data/docker-compose cat > docker-compose.yaml <&l ...

  3. OpenCompass-书生浦语大模型实战营第二期第7节作业

    书生浦语大模型实战营第二期第7节作业 这一节的作业和第6节作业一样没有特别多好说的,以运行结果为主. 基础作业 使用 OpenCompass 评测 internlm2-chat-1_8b 模型在 C- ...

  4. WEB服务与NGINX(5)- root和alias的区别详解

    root和alias的区别 root:指定站点家目录,给定的路径对应于location中的/uri 左侧的/,文件的绝对路径为root+location. 支持环境:http, server, loc ...

  5. HDU 多校 2023 Round #6 题解

    HDU 多校 2023 Round #6 题解 \(\text{By DaiRuiChen007}\) A. Count Problem Link 题目大意 求有多少个长度为 \(n\),字符集大小为 ...

  6. 当你用neovim的mason插件管理lsp config,并且配置好bash的bashls后,却没有正常工作的解决方式

    刚开始遇到这个情况我百思不得其解,检查了neovim checkhealth,以为是npm包管理的问题,然后删了下删了下 不但没有解决还把包管理整乱了-- 后来发现是我没仔细看bash-languag ...

  7. 在jeecg-boot中密码的使用

    1.生成密码并入库保存 String id= SnowflakeIdUtil.nextValue();//生成id operatCompany.setId(id); String salt = oCo ...

  8. 使用systemctl管理服务(nginx)

    首先调整好路径信息,修改配置文件vim /usr/lib/systemd/system/nginx.service [Unit]Description=The nginx HTTP and rever ...

  9. VAE-可变自动编码器

    VAE 有什么作用? 简而言之,它改进了生成的图像.VAE 针对图像的某些方面进行训练,并且我们的 UI ( vae-ft-mse-840000-ema-pruned) 中捆绑的默认 VAE 改善了生 ...

  10. git cherry-pick合并其它分支的某次提交(commits)到当前分支

    git cherry-pick 可以选择某一个分支中的一个或几个commit(s)来进行操作. 例如,假设我们有个稳定版本的分支,叫v2.0.0,另外还有个开发版本的分支v3.0.0,我们不能直接把两 ...