1、SpringMVC自动配置概览
2、功能简单分析
2.1、静态资源访问
(1)静态资源目录
类路径下:called /static
(or /public
or /resources
or /META-INF/resources
)
访问:当前项目路径/+静态资源名称
原理:静态映射/**
请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。静态资源找不到404
(2)静态资源访问前缀
默认无前缀
但是我们可以通过配置来修改前缀
spring.mvc.static-path-pattern=/res/**
(3)静态资源目录修改
可以指定到具体的自定义目录
spring.web.resources.static-locations=classpath:/file/
(4)Webjars技术
引入jar中的静态资源,自定映射jar包内容
https://www.webjars.org/
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
<version>3.6.0</version>
</dependency>
访问:本项目路径+/webjars/….
示例:http://localhost:8080/webjars/jquery/3.6.0/jquery.js
2.2、欢迎页
创建一个index.html存放在静态资源目录下,就可以访问到欢迎页,假如配置了访问前缀就只能按全路径进行访问,不然可以通过https://localhost:8080直接进行访问。
2.3、favicon.ico
favicon.icon直接存放在静态资源路径下就可以。
但是不能配置静态资源路径
3.4、静态资源配置原理
- SpringBoot启动目录加载xxxAutoConfiguration类(自动配置类)
SpringMVC自动配置基本都在WebMvcAutoConfiguration配置类、生效
@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 {
给容器中配了什么
@Configuration(proxyBeanMethods = false) @Import(EnableWebMvcConfiguration.class) @EnableConfigurationProperties({ WebMvcProperties.class, org.springframework.boot.autoconfigure.web.ResourceProperties.class, WebProperties.class }) @Order(0) public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
配置文件的相关属性和xxx进行了绑定。WebMvcProperties==spring.mvc、ResourceProperties==spring.resources、WebProperties==spring.web
只有一个有参构造器,所有参数都会从容器中找
//ListableBeanFactory beanFactory 容器工厂 //resourceHandlerRegistrationCustomizerProvider 资源处理器的自定义器 //servletRegistrations 给应用注册Servlet、Filter public WebMvcAutoConfigurationAdapter( org.springframework.boot.autoconfigure.web.ResourceProperties resourceProperties, WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
静态资源处理器
@Override public void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); return; } addResourceHandler(registry, "/webjars/**", "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); } }); }
可以通过addMapping配置禁用掉所有资源访问
spring.web.resources.add-mappings=false
配置了默认的静态资源路径
public static class Resources { 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;
欢迎页处理器源码规则
@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; }
WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) { if (welcomePage != null && "/**".equals(staticPathPattern)) { logger.info("Adding welcome page: " + welcomePage); setRootViewName("forward:index.html"); } else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) { logger.info("Adding welcome page template: index"); setRootViewName("index"); } }