springBoot是如何自动处理静态并映射静态资源的,直接上代码。
一、在springBoot autoconfigure jar包中,存在WebMvcAutoConfiguration 自动配置类,该类的生效条件是:存在Servlet ,DispatcheServlet ,WebMvcConfigurer这三个类,
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
以及不存在:自定义的WebMvc配置类
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
二、找到内部类:该内部类任然是一个配置类,由注解:@Configuration标识
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware
该自动配置类提供了一个有参构造器:参数从spring容器中获取。
①:ObjectProvider<HttpMessageConverters> messageConvertersProvider :消息转换器
②:WebProperties webProperties:配置属性
③:ListableBeanFactory beanFactory:IOC容器
④:ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider:资源处理自定义器
⑤:ObjectProvider<DispatcherServletPath> dispatcherServletPath:处理的路径
⑥:ObjectProvider<ServletRegistrationBean<?>> servletRegistrations:注册原生的Servlet组件例如:Servlet/Listener/Filter等,通过注解:@WebServlet @WebFilter @WebListener
public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties,
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
ObjectProvider<DispatcherServletPath> dispatcherServletPath,
ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
this.resourceProperties = webProperties.getResources();
this.mvcProperties = mvcProperties;
this.beanFactory = beanFactory;
this.messageConvertersProvider = messageConvertersProvider;
this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
this.dispatcherServletPath = dispatcherServletPath;
this.servletRegistrations = servletRegistrations;
this.mvcProperties.checkConfiguration();
}
配置消息转换器:
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
this.messageConvertersProvider
.ifAvailable((customConverters) -> converters.addAll(customConverters.getConverters()));
}
配置视图解析器:
@Bean
@ConditionalOnMissingBean
public InternalResourceViewResolver defaultViewResolver() {
InternalResourceViewResolver resolver = new InternalResourceViewResolver();
resolver.setPrefix(this.mvcProperties.getView().getPrefix());
resolver.setSuffix(this.mvcProperties.getView().getSuffix());
return resolver;
}
配置资源处理器:
通过:
#禁用静态资源规则
spring:
web:
resources:
add-mappings: true
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
//禁用静态资源,则后面的代码全部不生效
if (!this.resourceProperties.isAddMappings()) {
logger.debug("Default resource handling disabled");
return;
}
//处理webjars请求路径映射
addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
//private String staticPathPattern = "/**"; /**请求由下面代码处理
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);
}
});
}
//获取静态资源位置
this.resourceProperties.getStaticLocations()
该类通过:@EnableConfigurationProperties 绑定配置类:WebMvcProperties.class, WebProperties.class,实现自动配置。
@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
三、进入WebProperties 配置类中,该类通过配置文件注@ConfigurationProperties("spring.web")
找到配置文件中以:spring.web开头的配置,作为用户自定义配置属性。
四:欢迎页配置:WelcomePageHandlerMapping
@Bean
public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
this.mvcProperties.getStaticPathPattern());
welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
return welcomePageHandlerMapping;
}