Spring Boot web开发 - Spring MVC自动配置

·  阅读 153

查看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的默认配置:

  1. 自动配置ViewResolver(视图解析器:根据方法的返回值得到试图对象View,试图对象决定如何渲染,eg.转发?重定向?)
    ContentNegotiatingViewResolver: 组合所有的视图解析器
    如何定制:我们可以自己给容器添加一个视图解析器,ContentNegotiatingViewResolver会自动将其组合进来。

  2. 配置静态资源文件夹路径和Webjars

  3. 自动注册Converter, Formatter
    Converter:转换器;例如处理传入的对象类型public String hello(User user)负责类型转化
    Formatter:格式化器;2017.12.27===Date
    如何定制:  
    根据下图的源码所示,只要我们的程序中存在自定义的Converter,并放在容器中,就会被Spring Boot自动扫描并注册为Converter

    public 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);
    			}
    		}
    	}
    复制代码
  4. HttpMessageConverters(消息转换器):Spring MVC用来转换Http请求和响应的;eg. 程序返回的是User类型的对象,需要转换为Json格式写出。
    HttpMessageConverters是从容器中确定;获取所有HttpMessageConverter;
    定制:自己给容器中添加HttpMessageConverter,只需要将自己写的组件注册到容器中

  5. MessageCodesResolver(定义错误代码生成规则)

  6. 静态欢迎页index.html配置

  7. 自定义favicon配置

  8. 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 type WebMvcConfigurerAdapter, but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter 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默认配置

模式:

  1. SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己设置的(@Bean, @Component),如果有,就用用户配置的,如果没有,才自动配置;如果有些组件可以用多个(如Viewresolver),Spring Boot将用户配置的和自己默认的配置组合起来。
  2. 在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

Spring Boot Reference Guide官方文档

分类:
后端
标签:
分类:
后端
标签:
收藏成功!
已添加到「」, 点击更改