1、Spring Boot 的自动配置
Spring Boot 为 Spring MVC 提供了自动配置,适用于大多数应用程序。首先查看官方文档,看看 SpringBoot 对 Spring MVC 做了哪些配置。(官网)
自动配置在 Spring 的默认值之上添加了以下功能:
- 包含 ContentNegotiatingViewResolver 和 BeanNameViewResolver beans。
- 自动配置了 ViewResolver(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发或重定向))。
- ContentNegotiatingViewResolver:组合所有的视图解析器的;
- 我们可以自己给容器中添加一个视图解析器;自动的将其组合进来。
- 支持提供静态资源,包括对 WebJars 的支持。
- 自动注册 Converter , GenericConverter 和 Formatter beans。
- Converter:转换器; public String hello(User user) 和 JSON 类型转换使用 Converter。
- Formatter 格式化器; 2017.12.17 转换为 Date;
- 自己添加的格式化器转换器,我们只需要放在容器中即可。
- 支持 HttpMessageConverters
- HttpMessageConverter:Spring MVC 使用该 HttpMessageConverter 接口转换 HTTP 请求和响应;User—JSON;
- HttpMessageConverters 是从容器中确定;获取所有的 HttpMessageConverter 实现类;
- 自己给容器中添加 HttpMessageConverter,只需要将自己的组件注册容器中(@Bean,@Component)
- 自动注册 MessageCodesResolver 。
- MessageCodesResolver 定义渲染错误消息的策略
- 静态 index.html 支持
- 自定义 Favicon 支持
- 自动使用 ConfigurableWebBindingInitializer bean
- Spring MVC 使用 WebBindingInitializer 来初始化 WebDataBinder 特定请求。
- 可以配置一个 ConfigurableWebBindingInitializer 来替换默认的;(添加到容器)
如果你想保留 Spring Boot MVC 功能,并且你想添加额外的 MVC 配置(拦截器,格式化程序,视图控制器和其他功能),你可以添加自己的@Configuration 类(WebMvcConfigurer ),但不能添加 @EnableWebMvc 。如果您希望提供 RequestMappingHandlerMapping , RequestMappingHandlerAdapter 或 ExceptionHandlerExceptionResolver 的自定义实例,则可以声明 WebMvcRegistrationsAdapter 实例以提供此类组件。
如果您想完全控制 Spring MVC,可以添加自己的@Configuration 注释@EnableWebMvc 。
SpringBoot 对静态资源的映射规则
在 ResourceProperties 配置文件类中,可以看到静态资源的位置。
@ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
public class ResourceProperties {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
"classpath:/resources/", "classpath:/static/", "classpath:/public/" };
/**
* Locations of static resources. Defaults to classpath:[/META-INF/resources/,
* /resources/, /static/, /public/].
*/
private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;
Spring MVC 的配置 WebMvcAutoConfiguration
类中 addResourceHandlers
方法添加资源映射,所有 /webjars/**
,都去 classpath:/META-INF/resources/webjars/
找资源。
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
.addResourceLocations("classpath:/META-INF/resources/webjars/")
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
// 静态资源文件夹映射
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
/**
访问当前项目的任何资源,都去(静态资源的文件夹)找映射。例如:访问 localhost:8080/zyx
等于去静态资源文件夹里面找 zyx
。静态资源文件夹如下:
- "classpath:/META-INF/resources/",
- "classpath:/resources/",
- "classpath:/static/",
- "classpath:/public/
- "/": 当前项目的根路径
什么是 WebJars
WebJars 是被打包成 JAR 文件 (Java Archive)形式的客户端 Web 资源库(例如:jQuery、Bootstrap 等)。官网
例如导入一个 jquery
。
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.4.1</version>
</dependency>
访问路径为:http://localhost:8080/webjars/jquery/3.4.1/jquery.js
;目录结构为:
2、扩展 Spring MVC
编写一个配置类(@Configuration),是 WebMvcConfigurer 类型;不能标注@EnableWebMvc
视图映射功能
浏览器发送请求,SpringBoot 实现请求到相应页面,并且通过模板引擎解析。
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry){
// 浏览器发送 /aaa 请求到success
registry.addViewController("/aaa").setViewName("success");
}
}
原理
WebMvcAutoConfiguration
是 SpringMVC 的自动配置类。在 WebMvcAutoConfiguration
中有个内部类 WebMvcAutoConfigurationAdapter
实现了 WebMvcConfigurer
并导入了 EnableWebMvcConfiguration
组件。
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {
EnableWebMvcConfiguration
组件继承了 DelegatingWebMvcConfiguration
类。
@Configuration(proxyBeanMethods = false)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
DelegatingWebMvcConfiguration
类中有个方法,获取容器中所有的 WebMvcConfigurer
添加到 WebMvcConfigurerComposite
类中。
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
在 WebMvcConfigurerComposite
类中获取所有配置,都是将所有的 WebMvcConfigurer
实现类的配置综合到一起。所以扩展 Spring MVC 只需实现 WebMvcConfigurer
接口即可。
@Override
public void addViewControllers(ViewControllerRegistry registry) {
for (WebMvcConfigurer delegate : this.delegates) {
delegate.addViewControllers(registry);
}
}
3、全面接管 Spring MVC
我们在配置类中添加 @EnableWebMvc
注解,可以让 SpringBoot 对 SpringMVC 做的所有配置都失效。
原理
@EnableWebMvc
注解添加了 DelegatingWebMvcConfiguration
组件
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
而 DelegatingWebMvcConfiguration
继承 WebMvcConfigurationSupport
。
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
在 WebMvcAutoConfiguration
类中有 @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
,作用:如果容器中有 WebMvcConfigurationSupport
则 WebMvcAutoConfiguration
不生效。所以 SpringBoot 对 SpringMVC 做的所有配置就都失效。
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
@EnableWebMvc
将 WebMvcConfigurationSupport
组件导入进来,导入的 WebMvcConfigurationSupport
只是 SpringMVC 最基本的功能;
4、修改 SpringBoot 的默认配置
- SpringBoot 在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;
- 在 SpringBoot 中会有很多的 xxxConfigurer 帮助我们进行扩展配置。
- 在 SpringBoot 中会有很多的 xxxCustomizer 帮助我们进行定制配置。
标题:SpringBoot 配置之 SpringMVC 自动配置
作者:Yi-Xing
地址:http://47.94.239.232:10014/articles/2020/07/18/1595043715770.html
博客中若有不恰当的地方,请您一定要告诉我。前路崎岖,望我们可以互相帮助,并肩前行!