查看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
@Controller
or@RestController
beans to handle incoming HTTP requests. Methods in your controller are mapped to HTTP using@RequestMapping
annotations.
下面是典型的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
@Configuration
class of typeWebMvcConfigurerAdapter
, but without@EnableWebMvc
. If you wish to provide custom instances ofRequestMappingHandlerMapping
,RequestMappingHandlerAdapter
orExceptionHandlerExceptionResolver
you can declare aWebMvcRegistrationsAdapter
instance providing such components.If you want to take complete control of Spring MVC, you can add your own
@Configuration
annotated 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