查看Spring Boot对其他模块的自动配置,有两种途径,一是看官方文档介绍,二是翻源码。
文档介绍
Spring Boot Reference Guide官方文档简直太有用了,再放一次。
The Spring Web MVC framework (often referred to as simply ‘Spring MVC’) is a rich ‘model view controller’ web framework. Spring MVC lets you create special
@Controlleror@RestControllerbeans to handle incoming HTTP requests. Methods in your controller are mapped to HTTP using@RequestMappingannotations.
下面是典型的RestController类的例子:
@RestController
@RequestMapping(value="/users")
public class MyRestController {
@RequestMapping(value="/{user}", method=RequestMethod.GET)
public User getUser(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}/customers", method=RequestMethod.GET)
List<Customer> getUserCustomers(@PathVariable Long user) {
// ...
}
@RequestMapping(value="/{user}", method=RequestMethod.DELETE)
public User deleteUser(@PathVariable Long user) {
// ...
}
}
Spring Boot 对 Spring Mvc的自动配置
参考官方文档,下图为Spring MVC的默认配置:
-
自动配置ViewResolver(视图解析器:根据方法的返回值得到试图对象View,试图对象决定如何渲染,eg.转发?重定向?)
ContentNegotiatingViewResolver: 组合所有的视图解析器
如何定制:我们可以自己给容器添加一个视图解析器,ContentNegotiatingViewResolver会自动将其组合进来。 -
配置静态资源文件夹路径和Webjars
-
自动注册Converter, Formatter
Converter:转换器;例如处理传入的对象类型public String hello(User user)负责类型转化
Formatter:格式化器;2017.12.27===Date
如何定制:
根据下图的源码所示,只要我们的程序中存在自定义的Converter,并放在容器中,就会被Spring Boot自动扫描并注册为Converterpublic static void addBeans(FormatterRegistry registry, ListableBeanFactory beanFactory) { Set<Object> beans = new LinkedHashSet<>(); // 从beanFactory中找到所有Converter类型的Bean,添加到beans集合中 beans.addAll(beanFactory.getBeansOfType(GenericConverter.class).values()); beans.addAll(beanFactory.getBeansOfType(Converter.class).values()); beans.addAll(beanFactory.getBeansOfType(Printer.class).values()); beans.addAll(beanFactory.getBeansOfType(Parser.class).values()); // 遍历beans集合,把所有的bean注册相应类型的Converter for (Object bean : beans) { if (bean instanceof GenericConverter) { registry.addConverter((GenericConverter) bean); } else if (bean instanceof Converter) { registry.addConverter((Converter<?, ?>) bean); } else if (bean instanceof Formatter) { registry.addFormatter((Formatter<?>) bean); } else if (bean instanceof Printer) { registry.addPrinter((Printer<?>) bean); } else if (bean instanceof Parser) { registry.addParser((Parser<?>) bean); } } } -
HttpMessageConverters(消息转换器):Spring MVC用来转换Http请求和响应的;eg. 程序返回的是User类型的对象,需要转换为Json格式写出。
HttpMessageConverters是从容器中确定;获取所有HttpMessageConverter;
定制:自己给容器中添加HttpMessageConverter,只需要将自己写的组件注册到容器中 -
MessageCodesResolver(定义错误代码生成规则)
-
静态欢迎页index.html配置
-
自定义favicon配置
-
ConfigurableWebBindingInitializer(初始化web数据绑定器)
org.springframework.boot.autoconfigure.web: web的所有自动场景;
If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own
@Configurationclass of typeWebMvcConfigurerAdapter, but without@EnableWebMvc. If you wish to provide custom instances ofRequestMappingHandlerMapping,RequestMappingHandlerAdapterorExceptionHandlerExceptionResolveryou can declare aWebMvcRegistrationsAdapterinstance providing such components.If you want to take complete control of Spring MVC, you can add your own
@Configurationannotated with@EnableWebMvc.
如何修改Spring Boot默认配置
模式:
- SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己设置的(@Bean, @Component),如果有,就用用户配置的,如果没有,才自动配置;如果有些组件可以用多个(如Viewresolver),Spring Boot将用户配置的和自己默认的配置组合起来。
- 在Spring Boot中会有非常多的xxxConfigurer帮助我们进行拓展配置,需要自定义的时候,就去找相应的类
扩展SpringMVC
在使用Spring Boot之前,对Spring MVC用xml自定义配置示例:
<mvc:view-controller path="/greetings" view-name="success/"/>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello"/>
</mvc:interceptor>
</mvc:interceptors>
使用Spring Boot时,推荐使用配置类进行自定义配置,如下示例实现了与上图一样的作用:
@Configuration
class WebMvcConfig: WebMvcConfigurer {
override fun addCorsMappings(registry: CorsRegistry) {
super.addCorsMappings(registry)
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("*")
.allowedHeaders("*")
}
override fun addViewControllers(registry: ViewControllerRegistry) {
super.addViewControllers(registry)
// 浏览器发送/demo请求,回来到greetings页面
registry.addViewController("/greetings").setViewName("success")
}
}
过程:编写了一个配置类(@Configuration),是WebMvcConfigurer类型,重写需要自动配置的方法。下图展示了我们可以重写的方法有哪些:
我们自己写的WebMvcConfig类会最终起作用,是因为它已经被加载到了容器中,过程如下图:
总结:容器中所有的WebMvcConfigurer都会一起起作用,所以我们的配置类也会被调用。
全面接管Spring MVC
Spring Boot对Spring MVC的自动配置全部抹掉,所有都自己配。只需要在我们自己的配置类上加@EnableWebMvc注解。
为什么加这个注解会有全面接管Spring MVC的效果:
Reference:
B站教程 P32