文章目录
源码在哪?
看看这个怎么才能生效
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@ConditionalOnClass({
Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
@ConditionalOnMissingBean({
WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({
DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
都干了什么WebMvcAutoConfigurationAdapter?
这个是我们要主要研究的东西
这个注解把下面两个类和这个方法绑定了起来
WebMvcProperties 跟什么绑定?
可以看到这个是读取配置文件中的以
为前缀的配置
ResourceProperties 配置了啥
跟上面的分析方法一样这里就不赘述了
我们的配置类只有一个有参构造器会发生什么?
配置类只有一个有参构造器
//有参构造器所有参数的值都会从容器中确定
//ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象
//WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
//ListableBeanFactory beanFactory Spring的beanFactory
//HttpMessageConverters 找到所有的HttpMessageConverters
//ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。=========
//DispatcherServletPath
//ServletRegistrationBean 给应用注册Servlet、Filter....
public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
ObjectProvider<DispatcherServletPath> dispatcherServletPath,
ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
this.resourceProperties = resourceProperties;
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConvertersProvider = messageConvertersProvider;
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
this.dispatcherServletPath = dispatcherServletPath;
this.servletRegistrations = servletRegistrations;
}
- 有参构造器所有参数的值都会从容器中确定
- ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象 上面我们已经分析过它是怎么导入配置的
- WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象 上面我们已经分析过它是怎么导入配置的
- ListableBeanFactory beanFactory Spring的beanFactory
- HttpMessageConverters 找到所有的HttpMessageConverters
- ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器。
- DispatcherServletPath ServletRegistrationBean 给应用注册Servlet、Filter…
资源处理的默认规则
public void addResourceHandlers(ResourceHandlerRegistry registry) {
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
} else {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{
"/webjars/**"}).addResourceLocations(new String[]{
"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{
staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
}
}
我们来细嗦第一个if
这个
this.resourceProperties 是上面我们已经说过的读取配置文件 就是下面这个
这个方法是返回一个 addMappings 的值 这个addMappings默认是true
然后这个if 就会不生效就会执行下面的
这些东西才是我们的默认静态资源配置
怎么禁用默认配置
既然它是从配置文件读取的
我们把配置文件里面的改一下不就行了 让第一个if 里面的方法执行 不执行下面的默认配置就行了
细嗦默认的静态资源配置
else {
Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
if (!registry.hasMappingForPattern("/webjars/**")) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{
"/webjars/**"}).addResourceLocations(new String[]{
"classpath:/META-INF/resources/webjars/"}).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{
staticPathPattern}).addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
这一行是读取配置文件里面的缓存配置
下面这一行是拿到了缓存的配置
向registry访问规则里面注册 注册的第一种访问规则 “/webjars/**”
if (!registry.hasMappingForPattern("/webjars/**")) {
this.customizeResourceHandlerRegistration
(
registry.addResourceHandler
(new String[]{
"/webjars/**"}
)
.addResourceLocations(
new String[]{
"classpath:/META-INF/resources/webjars/"}
)
.setCachePeriod(this.getSeconds(cachePeriod))
.setCacheControl(cacheControl));
}
/webjars/**下的所有请求都会往
“classpath:/META-INF/resources/webjars/”
这里面去找
拿jQuery这个举个例子
wbjars的去/META-INF/resources/webjars/这里面找
现在我们来看第一个if下面的东西
String staticPathPattern = this.mvcProperties.getStaticPathPattern();
if (!registry.hasMappingForPattern(staticPathPattern)) {
this.customizeResourceHandlerRegistration(registry
.addResourceHandler(new String[]{
staticPathPattern}
)
.addResourceLocations(WebMvcAutoConfiguration.getResourceLocations(this.resourceProperties.getStaticLocations())).setCachePeriod(this.getSeconds(cachePeriod)).setCacheControl(cacheControl));
}
我们看这个get的是什么
这是在是spring.mvc里面配置的东西
如果这个没配的话就默认是
下面的if跟我们之前说的if里面的功能都是一样的
只不过下面的这个用的是这些默认配置
@ConfigurationProperties(
prefix = "spring.resources",
ignoreUnknownFields = false
)
public class ResourceProperties {
private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{
"classpath:/META-INF/resources/",
"classpath:/resources/",
"classpath:/static/",
"classpath:/public/"};
欢迎页的处理规则
HandlerMapping:处理器映射。保存了每一个Handler能处理哪些请求。
简单来说就是配置了 那个请求 谁去处理
通过调用反射调用能处理的方法
@Bean
//这里面的参数都是从IOC容器里面拿的
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext, FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(new TemplateAvailabilityProviders(applicationContext), applicationContext, this.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(this.getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(this.getCorsConfigurations());
return welcomePageHandlerMapping;
}
我们看这个new后边
这不就是我们配置的欢迎页地址吗