四、WebMvcAutoConfiguration原理
# 1. 生效条件
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class }) //在这些自动配置之后
@ConditionalOnWebApplication(type = Type.SERVLET) //如果是SERVLET类型web应用就生效。相对的还有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
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
# 2. 效果
放了两个Filter:
HiddenHttpMethodFilter
;页面表单提交Rest请求(GET、POST、PUT、DELETE)FormContentFilter
: 表单内容Filter,GET(数据放URL后面)、POST(数据放请求体)请求可以携带数据,PUT、DELETE 的请求体数据会被忽略
给容器中放了
WebMvcConfigurer
组件(代码如下,创建了一个实现了WebMvcConfigurer接口的配置类组件);给SpringMVC添加各种定制功能- 所有的功能最终会和配置文件进行绑定
- WebMvcProperties:
spring.mvc
配置文件 - WebProperties:
spring.web
配置文件
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class) //额外导入了其他配置
@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware{
}
1
2
3
4
5
6
7
2
3
4
5
6
7
# 3. WebMvcConfigurer接口
提供了配置SpringMVC底层的所有组件入口
# 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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
规则一:访问:
/webjars/**
路径就去classpath:/META-INF/resources/webjars/
下找资源.- maven 导入依赖
- 直接在浏览器里访问包里的js等静态文件
规则二:访问:
/**
路径就去静态资源默认的四个位置找资源
classpath:/META-INF/resources/
classpath:/resources/
classpath:/static/
classpath:/public/
规则三:静态资源默认都有缓存规则的设置
- 所有缓存的设置,直接通过配置文件:
spring.web
- cachePeriod: 缓存周期; 多久不用找服务器要新的。 默认没有,以s为单位
- cacheControl: HTTP缓存控制;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching (opens new window)
- useLastModified:是否使用最后一次修改。配合HTTP Cache规则
- 所有缓存的设置,直接通过配置文件:
如果浏览器访问了一个静态资源 index.js
,如果服务这个资源没有发生变化,下次访问的时候就可以直接让浏览器用自己缓存中的东西,而不用给服务器发请求。但这中间还是要发一次请求询问一下资源是否修改,根据修改的时间判断。
registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));// 对应配置文件中的spring.web.resources.cache.period
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());// 对应配置文件中的spring.web.resources.cache.cachecontrol
registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());// 对应配置文件中的spring.web.resources.cache.use-last-modified
1
2
3
2
3
# 缓存实验
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# 5. EnableWebMvcConfiguration源码
//SpringBoot 给容器中放 WebMvcConfigurationSupport 组件。
//我们如果自己放了 WebMvcConfigurationSupport 组件,Boot的WebMvcAutoConfiguration都会失效。
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebProperties.class)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware
{
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
HandlerMapping
: 根据请求路径/a
找那个handler能处理请求例如
WelcomePageHandlerMapping
:- 访问
/**
路径下的所有请求,都在以前四个静态资源路径下找,欢迎页也一样 - 找
index.html
:只要静态资源的位置有一个index.html
页面,项目启动默认访问
- 访问
# 6. 为什们容器中放一个WebMvcConfigurer
就能配置底层行为
WebMvcAutoConfiguration
是一个自动配置类,它里面有一个EnableWebMvcConfiguration
EnableWebMvcConfiguration
继承于DelegatingWebMvcConfiguration
,这两个都生效DelegatingWebMvcConfiguration
利用 DI 把容器中 所有WebMvcConfigurer
注入进来,包括我们自己写的- 别人调用
DelegatingWebMvcConfiguration
的方法配置底层规则,而它调用所有WebMvcConfigurer
的配置底层方法。
# 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);
1
2
3
4
2
3
4
编辑 (opens new window)
上次更新: 2024/05/30, 07:49:34