SpringBoot的Web相关配置
一、自动配置
- 正如前面所说,SpringBoot 提倡少配置或零配置,而要做到这样,也就意味着 Spring Boot 这个框架得为开发者事先配置好必须得配置,从而才能有自动配置得功能。Spring Boot 提供了这几个方面得自动配置:ViewResolver自动配置、静态资源自动配置、Formatter自动配置、Converter自动配置、HttpMessageConverters自动配置和静态首页配置。
1、ViewResolver 的自动配置
1.1、ContentNegotiatingViewResolver
- 这是 Spring MVC 提供的一个特殊的 ViewResolver,用于代理不同的 ViewResolver 来处理不同的 View 来渲染视图,拥有最高的优先级。
1.2、BeanNameViewResolver
- 先看个例子:
// Bean of BeanNameViewResolver @Bean public BeanBameViewResolver beanNameViewResolver(){ BeanNameViewResolver resolver = new BeanNameViewResolver(); return resolver; } // bean of view @Bean public MappingJackson2JsonView jsonView(){ MappingJackson2JsonView jsonView = new MappingJackson2JsonView(); return hsonView; } // in controller @RequestMapping(value="/json",produces={MediaType.APPLICATION_JSON_VALUE}) public String json(Model model){ Person single = new Person("test",11); model.addAttribute("demo",single); return "jsonView"; }
- 也就是说,在控制器(@Controller)中的方法返回的视图名会根据 BeanNameViewResolver 去查找 Bean 的名称和视图名一样的来渲染视图。
1.3、InternetResourceViewResolver
- 该 ViewResolver 主要通过设置前缀、后缀,以及控制器中的方法来返回视图名的字符串,从而得到实际页面。
- 以上 Resolver 方法都在 WebMvcAutoConfiguration 源文件中,位于org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration
2、静态资源的自动配置
- 先看一下位于 WebMvcAutoConfiguration 中的 addResourceHandles 方法的源代码:
public void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); } else { Integer cachePeriod = this.resourceProperties.getCachePeriod(); if (!registry.hasMappingForPattern("/webjars/**")) { registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(cachePeriod); } if (!registry.hasMappingForPattern("/**")) { registry.addResourceHandler(new String[]{"/**"}).addResourceLocations(WebMvcAutoConfiguration.RESOURCE_LOCATIONS).setCachePeriod(cachePeriod); } } }
- 从上面可以看出 Spring Boot 对静态资源地自动配置可分为两个方面:类路径文件和 webjar。
- 对于类路径文件,把类路径下地 /static、/public、/resources 以及 /META_INF/resources 文件下的静态文件直接映射成 /**。
- webjar 是指将我们常用的脚本框架封装在 jar 包中的 jar 包,将类路径下的 /META-INF/resources/webjars/ 中的静态文件直接映射成 /webjar/** 。
3、Formatter 和 Converter
- 它们的源代码如下:
public void addFormatters(FormatterRegistry registry) { Iterator var2 = this.getBeansOfType(Converter.class).iterator(); while(var2.hasNext()) { Converter<?, ?> converter = (Converter)var2.next(); registry.addConverter(converter); } var2 = this.getBeansOfType(GenericConverter.class).iterator(); while(var2.hasNext()) { GenericConverter converter = (GenericConverter)var2.next(); registry.addConverter(converter); } var2 = this.getBeansOfType(Formatter.class).iterator(); while(var2.hasNext()) { Formatter<?> formatter = (Formatter)var2.next(); registry.addFormatter(formatter); } } private <T> Collection<T> getBeansOfType(Class<T> type) { return this.beanFactory.getBeansOfType(type).values(); }
- 由上可以看出,只要我们定义了 Converter、GenericConverter 和 Formatter 接口的实现类的 Bean,便会被自动注册到 Spring MVC 中。
4、messageConverters
- 同样的先看源码:
@Autowired private HttpMessageConverters messageConverters; public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.addAll(this.messageConverters.getConverters()); }
- 通过 @Autowired 自动扫描所有的 HttpMessageConverter 然后自动加入到 HttpMessageConverter list 中。
- 一旦需要新增自定义 HttpMessageConverter,只需要定义一个 HttpMessageConverters 的 Bean并在 Bean 里面注册自定义的 HttpMessageConverter 即可,例如:
@Bean public HttpMessagesConverters testConverters(){ HttpMessageConverter<?> test = new TestCustomConverter(); return new HttpMessageConverters(test); }
5、首页的配置
- 把静态 index.html 文件放置在如下目录:
classpath:/META-INF/resources/index.html classpath:/resources/index.html classpath:/static/index.html classpath:/public/index.html
- 打开浏览器访问 http://localhost:8080/ 时就会直接映射。
二、手动配置
- 当 Spring Boot 的默认配置无法满足需求时,可以自己定义一个配置类,注解上 @EnableWebMvc 或者是继承自 WebMvcConfigurerAdapter,例如:
import org.springframework.boot.autoconfigure.web.WebMvcAutoConfiguration; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.ViewControllerRegistry; @Configuration public class WebMvcConfig extends WebMvcAutoConfiguration.WebMvcAutoConfigurationAdapter { @Override public void addViewControllers(ViewControllerRegistry registry){ registry.addViewController("/xx").setViewName("/xx"); } }
- 采用第二种方式的好处就是,我们自定义的配置和 Spring Boot 的默认配置同时都有效。