知世故而不世故 是善良的成熟
文章目录
- 1.1 生效条件
- 1.2 效果
- 1.3 WebMvcConfigure接口
- 1.4 静态资源规则代码
- 1.5 EnableWebMvcConfiguration源码
- 1.6 为什么容器中放一个WebMvcConfigure就能配置底层行为
- 1.7 WebMvcConfigurationSupport
1、WebMvcAutoConfiguration
1.1 生效条件
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class }) //在这些自动配置之后 @ConditionalOnWebApplication(type = Type.SERVLET) //如果是web应用就生效,类型SERVLET、REACTIVE 响应式web @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class }) @ConditionalOnMissingBean(WebMvcConfigurationSupport.class) //容器中没有这个Bean,才生效。默认就是没有 @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)//优先级 @ImportRuntimeHints(WebResourcesRuntimeHints.class) public class WebMvcAutoConfiguration { }
1.2 效果
1、放了两个Filter:
(1)HiddenHttpMethodFilter:页面表单提交Rest请求(GET、POST、PUT、DELETE)
(2)FormContentFilter:表单内容Filter,GET(数据放URL后面)、POST(数据放请求体)请求可以携带数据、PUT、DELETE的请求体数据会被忽略
2、给容器中放了WebMVcConfigure组件:给SpringMVC添加各种定制功能
(1)所有的功能最终会和配置文件进行绑定
(2)WebMvcProperties:spring.mvc配置文件
(3)WebProperties:spring.web配置文件
@Configuration(proxyBeanMethods = false) @Import(EnableWebMvcConfiguration.class) //额外导入了其他配置 @EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class }) @Order(0) public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware{ }
1.3 WebMvcConfigure接口
提供配置SpringMVC底层的所有组件入口
1.4 静态资源规则代码
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); return; } //1、 addResourceHandler(registry, this.mvcProperties.getWebjarsPathPattern(), "classpath:/META-INF/resources/webjars/"); addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> { registration.addResourceLocations(this.resourceProperties.getStaticLocations()); if (this.servletContext != null) { ServletContextResource resource = new ServletContextResource(this.servletContext, SERVLET_LOCATION); registration.addResourceLocations(resource); } }); }
1、规则一:访问:/webjars/** 路径就去classpath:/META-INF/resources/webjars/下找资源。 (1)maven导入依赖 2、规则二:访问:/** 路径就去静态资源默认的四个位置找资源 (1)classpath:/META-INF/resources/ (2)classpath:/resources (3)classpath:static/ (4)classpath:/public/ 3、规则三:静态资源默认都有缓存规则的设置 (1)所有缓存的设置,直接通过配置文件:spring.web (2)cachePeriod:缓存周期。多久不用找服务器要新的。默认没有,以s为单位 (3)cacheControl:HTTP缓存控制:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching (4)useLastModified:是否使用最后一次修改。配合HTTP Cache规则
如果浏览器访问了一个静态资源index.js,如果服务这个资源没有发生变化,下次访问的时候就可以直接让浏览器用直接缓存中的东西,而不用给服务器发请求。
registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod())); registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl()); registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());
1.5 EnableWebMvcConfiguration源码
//SpringBoot 给容器中放 WebMvcConfigurationSupport 组件。 //我们如果自己放了 WebMvcConfigurationSupport 组件,Boot的WebMvcAutoConfiguration都会失效。 @Configuration(proxyBeanMethods = false) @EnableConfigurationProperties(WebProperties.class) public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware { }
1、HandlerMapping:根据请求路径/a找那个handler能处理请求
(1)welcomePageHandlerMapping:
i. 访问/**路径下的所有请求,都在以前四个静态资源路径下找,欢迎页也一样
ii. 找index.html:只要静态资源的位置有一个index.html页面,项目启动默认访问
1.6 为什么容器中放一个WebMvcConfigure就能配置底层行为
1、WebMvcConfiguration是一个自动配置类,它里面有一个EnableWebMvcConfiguration
2、EnableWebConfiguration继承与DelegatingWebMvcConfiguration,这两个都能生效
3、DelegatingWebMvcConfiguration的方法配置底层规则,而它调用所有WebMvcConfigurer的配置底层方法。
1.7 WebMvcConfigurationSupport
提供了很多的默认设置。
判断系统中是否有相应的类:如果有,就加入相应的HttpMessageConverter
jackson2Present = ClassUtils.isPresent("com.fasterxml.jackson.databind.ObjectMapper", classLoader) && ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", classLoader); jackson2XmlPresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader); jackson2SmilePresent = ClassUtils.isPresent("com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader);
2、Web场景
2.1 自动配置
1、整合web场景
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
2、引入了autoconfigure
3、@EnableAutoConfiguration注解使用@Import(AutoConfigurationImportSelector.class)批量导入组件
4、加载META-INF/spring/org/springframework.boot.autoconfigure.AutoConfiguration.imports文件中配置的所有组件
5、所有自动配置类如下
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration ====以下是响应式web场景和现在的没关系====== org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.ReactiveMultipartAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.WebSessionIdResolverAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration ================以上没关系================= org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration
6、绑定了配置文件的一堆配置
(1)SpringMvc的所有配置spring.mvc
(2)Web场景通用配置spring.web
(3)文件上传配置spring.servlet.multipart
(4)服务器的配置server:比如:编码方式
2.2 默认效果
默认配置:
1、包含了 ContentNegotiatingViewResolver 和 BeanNameViewResolver 组件,方便视图解析
2、默认的静态资源处理机制: 静态资源放在 static 文件夹下即可直接访问
3、自动注册了 Converter,GenericConverter,Formatter组件,适配常见数据类型转换和格式化需求
4、支持 HttpMessageConverters,可以方便返回json等数据类型
5、注册 MessageCodesResolver,方便国际化及错误消息处理
6、支持 静态 index.html
7、自动使用ConfigurableWebBindingInitializer,实现消息处理、数据绑定、类型转化、数据校验等功能
重要:
如果想保持boot mvc 的默认配置,并且自定义更多的 mvc 配置,如:interceptors, formatters, view controllers 等。可以使用@Configuration注解添加一个 WebMvcConfigurer 类型的配置类,并不要标注 @EnableWebMvc
如果想保持 boot mvc 的默认配置,但要自定义核心组件实例,比如:RequestMappingHandlerMapping, RequestMappingHandlerAdapter, 或ExceptionHandlerExceptionResolver,给容器中放一个 WebMvcRegistrations 组件即可
如果想全面接管 Spring MVC,@Configuration 标注一个配置类,并加上 @EnableWebMvc注解,实现 WebMvcConfigurer 接口
3、静态资源
3.1 默认规则
3.1.1 静态资源映射
静态资源映射规则在WebMvcAutoConfiguration中进行了定义:
1、/webjars/** 的所有路径 资源都在 classpath:/META-INF/resources/webjars/
2、/** 的所有路径 资源都在 classpath:/META-INF/resources/、classpath:/resources/、classpath:/static/、classpath:/public/
3、所有静态资源都定义了缓存规则。【浏览器访问过一次,就会缓存一段时间】,但此功能参数无默认值
(1) period: 缓存间隔。 默认 0S;
(2) cacheControl:缓存控制。 默认无;
(3) useLastModified:是否使用lastModified头。 默认 false;
3.1.2 静态资源缓存
如前面所述
所有静态资源都定义了缓存规则。【浏览器访问过一次,就会缓存一段时间】,但此功能参数无默认值
a. period: 缓存间隔。 默认 0S;
b. cacheControl:缓存控制。 默认无;
c. useLastModified:是否使用lastModified头。 默认 false;
3.1.3 欢迎页
欢迎页规则在WebMvcAutoConfiguration中进行了定义:
1、在静态资源目录下找index.html
2、没有就在template下找index模板页
3.1.4 Favcion
1、在静态资源目录下找favicon.ico
3.1.5 缓存实验
server.port=9000 #1、spring.web: # 1.配置国际化的区域信息 # 2.静态资源策略(开启、处理链、缓存) #开启静态资源映射规则 spring.web.resources.add-mappings=true #设置缓存 #spring.web.resources.cache.period=3600 ##缓存详细合并项控制,覆盖period配置: ## 浏览器第一次请求服务器,服务器告诉浏览器此资源缓存7200秒,7200秒以内的所有此资源访问不用发给服务器请求,7200秒以后发请求给服务器 spring.web.resources.cache.cachecontrol.max-age=7200 #使用资源 last-modified 时间,来对比服务器和浏览器的资源是否相同没有变化。相同返回 304 spring.web.resources.cache.use-last-modified=true
3.2 自定义静态资源规则
自定义静态资源路径、自定义缓存规则
3.2.1 配置方式
spring.mvc:静态资源访问前缀路径
spring.web:
- 静态资源目录
- 静态资源缓存策略
#1、spring.web: # 1.配置国际化的区域信息 # 2.静态资源策略(开启、处理链、缓存) #开启静态资源映射规则 spring.web.resources.add-mappings=true #设置缓存 spring.web.resources.cache.period=3600 ##缓存详细合并项控制,覆盖period配置: ## 浏览器第一次请求服务器,服务器告诉浏览器此资源缓存7200秒,7200秒以内的所有此资源访问不用发给服务器请求,7200秒以后发请求给服务器 spring.web.resources.cache.cachecontrol.max-age=7200 ## 共享缓存 spring.web.resources.cache.cachecontrol.cache-public=true #使用资源 last-modified 时间,来对比服务器和浏览器的资源是否相同没有变化。相同返回 304 spring.web.resources.cache.use-last-modified=true #自定义静态资源文件夹位置 spring.web.resources.static-locations=classpath:/a/,classpath:/b/,classpath:/static/ #2、 spring.mvc ## 2.1. 自定义webjars路径前缀 spring.mvc.webjars-path-pattern=/wj/** ## 2.2. 静态资源访问路径前缀 spring.mvc.static-path-pattern=/static/**
3.2.2 代码方式
容器中只要有一个WebMvcConfigurer组件。配置的底层行为都会生效
@EnableWebMvc//禁用boot的默认配置
@Configuration //这是一个配置类 public class MyConfig implements WebMvcConfigurer { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { //保留以前规则 //自己写新的规则。 registry.addResourceHandler("/static/**") .addResourceLocations("classpath:/a/","classpath:/b/") .setCacheControl(CacheControl.maxAge(1180, TimeUnit.SECONDS)); } }
@Configuration //这是一个配置类,给容器中放一个 WebMvcConfigurer 组件,就能自定义底层 public class MyConfig /*implements WebMvcConfigurer*/ { @Bean public WebMvcConfigurer webMvcConfigurer(){ return new WebMvcConfigurer() { @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { registry.addResourceHandler("/static/**") .addResourceLocations("classpath:/a/", "classpath:/b/") .setCacheControl(CacheControl.maxAge(1180, TimeUnit.SECONDS)); } }; } }
2.3 路径匹配
Spring5.3之后加入了更多的请求路径匹配的实现策略:
以前只支持AntPathMatcher,现在提供了PathPatternParser策略。并且可以让我们指定到底使用哪种策略。
2.3.1 Ant风格路径用法
Ant风格的路径模式语法具有以下规则:
*:表示任意数量的字符
?:表示任意一个字符
**:表示任意数量的目录
{}:表示一个命名的模式占位符
[]:表示字符集合,例如[a-z]表示小写字母。
例如:
*.html 匹配任意名称,扩展名为.html的文件
/folder1//.jsp匹配早folder1目录下的任意两级目录下的.java文件
/folder2/**/*.jsp 匹配在folder2目录下任意目录深度的.jsp文件
/{type}/{id}.html匹配任意文件为{id}.html,在任意命名的{type}目录下的文件
注意:Ant风格的路径匹配语法中的特色字符需要转义,如:
要匹配文件路径中的星号,则需要转义为\*。
要匹配文件路径中的问号,则需要转义为\?。
2.3.2 模式切换
AntPathMatcher 与 PathPatternParser
● PathPatternParser 在 jmh 基准测试下,有 6~8 倍吞吐量提升,降低 30%~40%空间分配率
● PathPatternParser 兼容 AntPathMatcher语法,并支持更多类型的路径模式
● PathPatternParser “**” 多段匹配的支持仅允许在模式末尾使用
@GetMapping("/a*/b?/{p1:[a-f]+}") public String hello(HttpServletRequest request, @PathVariable("p1") String path) { log.info("路径变量p1: {}", path); //获取请求路径 String uri = request.getRequestURI(); return uri; }
总结:
● 使用默认的路径匹配规则,是由 PathPatternParser 提供的
● 如果路径中间需要有 **,替换成ant风格路径
# 改变路径匹配策略: # ant_path_matcher 老版策略; # path_pattern_parser 新版策略; spring.mvc.pathmatch.matching-strategy=ant_path_matcher
您的支持是我创作的无限动力
希望我能为您的未来尽绵薄之力
如有错误,谢谢指正若有收获,谢谢赞美