SpringBoot对SpringMVC的自动配置,你知道多少?


SpringBoot对SpringMVC的自动配置,你知道多少?

文章插图
Spring MVC自动配置Spring Boot为Spring MVC提供了自动配置,可以在大多数应用程序中很好地工作 。
自动配置在Spring默认的基础上添加了以下特性:
  • 包含ContentNegotiatingViewResolver和BeanNameViewResolver bean 。
  • 支持提供静态资源,包括对WebJars的支持 。
  • 自动注册Converter、GenericConverter和Formatter
  • 对HttpMessageConverters的支持 。
  • MessageCodesResolver的自动注册 。
  • 静态index.html支持 。
  • 自动使用ConfigurableWebBindingInitializer bean 。
如果你想保留这些Spring Boot MVC自定义并进行更多的MVC自定义(拦截器、格式化器、视图控制器和其他特性),你可以自定义配置类实现WebMvcConfigurer类型的@Configuration类,但不需要@EnableWebMvc 。
如果你想提供RequestMAppingHandlerMapping、RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,并且仍然保持Spring Boot MVC自定义,你可以声明一个WebMvcRegistrations类型的bean,并使用它来提供这些组件的自定义实例,源码如下:
public interface WebMvcRegistrations {default RequestMappingHandlerMapping getRequestMappingHandlerMapping() {return null;}default RequestMappingHandlerAdapter getRequestMappingHandlerAdapter() {return null;}default ExceptionHandlerExceptionResolver getExceptionHandlerExceptionResolver() {return null;}}EnableWebMvcConfiguration
public static class EnableWebMvcConfiguration {private final WebMvcRegistrations mvcRegistrations;public EnableWebMvcConfiguration(ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider) {this.mvcRegistrations = mvcRegistrationsProvider.getIfUnique();}@Overrideprotected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {// 如果自定义了WebMvcRegistrations,则使用自定义的,其他的默认配置行为不变if (this.mvcRegistrations != null) {RequestMappingHandlerAdapter adapter = this.mvcRegistrations.getRequestMappingHandlerAdapter();if (adapter != null) {return adapter;}}return super.createRequestMappingHandlerAdapter();}}如果你想要完全控制Spring MVC,你可以添加你自己的@Configuration注解@EnableWebMvc,或者自定义配置类该类继承DelegatingWebMvcConfiguration并使用@Configuration注解 。
消息转换HttpMessageConvertersSpringMVC使用HttpMessageConverter接口来转换HTTP请求和响应 。明智的默认值是开箱即用的 。例如,对象可以自动转换为JSON(通过使用Jackson库)或XML(通过使用JacksonXML扩展(如果可用),或者通过使用JAXB(如果Jackson XML扩展不可用)) 。默认情况下,字符串以UTF-8编码 。
如果需要添加或自定义转换器,可以使用Spring Boot的HttpMessageConverters类,如以下列表所示:
@Configuration(proxyBeanMethods = false)public class CustomHttpMessageConvertersConfiguration {@Beanpublic HttpMessageConverters customConverters() {HttpMessageConverter<?> additional = new AdditionalHttpMessageConverter();HttpMessageConverter<?> another = new AnotherHttpMessageConverter();return new HttpMessageConverters(additional, another);}}系统默认也提供了HttpMessageConverters Bean,其实我们可以直接将自定义的HttpMessageConverter注册为Bean即可:
public class HttpMessageConvertersAutoConfiguration {@Bean@ConditionalOnMissingBean// 这里的参数就能够收集所有HttpMessageConverter类型的Beanpublic HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));}}自定义JSON序列化和反序列化如果你使用Jackson来序列化和反序列化JSON数据,你可能需要编写自己的JsonSerializer和JsonDeserializer类 。自定义序列化程序通常通过一个模块向Jackson注册,但Spring Boot提供了一个替代的@JsonComponent注释,可以更容易地直接注册Spring Beans 。
你可以在JsonSerializer、JsonDeserializer或KeyDeserialize实现上直接使用@JsonComponent注释 。您也可以在包含序列化程序/反序列化程序作为内部类的类上使用它,如以下示例所示:
@JsonComponentpublic class MyJsonComponent {public static class Serializer extends JsonSerializer<MyObject> {@Overridepublic void serialize(MyObject value, JsonGenerator jgen, SerializerProvider serializers) throws IOException {jgen.writeStartObject();jgen.writeStringField("name", value.getName());jgen.writeNumberField("age", value.getAge());jgen.writeEndObject();}}public static class Deserializer extends JsonDeserializer<MyObject> {@Overridepublic MyObject deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {ObjectCodec codec = jsonParser.getCodec();JsonNode tree = codec.readTree(jsonParser);String name = tree.get("name").textValue();int age = tree.get("age").intValue();return new MyObject(name, age);}}}


推荐阅读