SpringBoot 6. Web 场景
1. 简单功能分析
1.1 静态资源访问
1.1.1 静态资源目录
默认为类路径下:
/static
,/public
,/resources
,/META-INF/resources
访问:http://localhost:8080/资源文件名
即可。
请求进来,会先去找 Controller
能不能处理请求,若不能,则将请求交给静态资源处理器。若静态资源也找不到,就会 404
。
1.1.2 静态资源访问前缀
有时候我们会做一些拦截器之类的功能,所以一般我们对静态资源的访问会带上前缀。
默认是没有前缀的,即 /**
。若我们想让将所有静态资源重新定位到 /resources/**
可以实现如下:
spring:
mvc:
static-path-pattern: "/resources/**"
访问:http://localhost:8080/resources/静态资源名
即可。
还可以设置 spring.web.resources.static-locations
属性自定义静态资源位置(将默认值替换为目录位置列表)。
spring:
mvc:
static-path-pattern: "/resources/**"
web:
resources:
static-locations: "classpath:/public"
上述意思就是,访问 http://localhost:8080/resources/静态资源名
会去 /resources/public
下面去找:
spring.web.resources.static-locations
属性还可以写成列表,表示可以去多个目录下找静态资源:
spring:
mvc:
static-path-pattern: /resources/**
web:
resources:
static-locations: [classpath:/public, classpath:/static]
1.2.3 引入 Webjars
就是把前端的 js 文件 css 文件框架之类的引入进来。只需要导依赖即可。
在 https://www.webjars.org/ 找到相关的依赖导入。
<dependency>
<groupId>org.webjars.npm</groupId>
<artifactId>jquery</artifactId>
<version>3.6.1</version>
</dependency>
然后通过 /webjars/路径
即可访问:http://localhost:8080/webjars/jquery/3.6.1/dist/jquery.js
1.2 欢迎页
先把 yaml
中的内容去掉。因为要去掉默认静态资源访问前缀,否则导致 index.html
不能被默认访问。
在静态资源访问路径下创建 index.html
。
访问 http://localhost:8080/
时默认就是访问刚才创建的 index.html
。
1.3 自定义图标
favicon.ico
在配置的静态内容位置中检查。
2. 静态资源配置原理
- SpringBoot 启动默认加载
xxxxAutoConfiguration
类(自动配置类)。 - 找到
spring-boot-autoconfigure
包下的web/servlet/WebMvcAutoConfiguration
类。
可以看到上面的注解:
@AutoConfiguration(after = { DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
给容器中配了什么功能:
@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
}
配置文件的相关属性和 xxx 进行了绑定:
WebMvcProperties
→ \to → spring.mvcWebProperties
→ \to → spring.web
一个配置类只有一个有参构造器,有参构造器所有的参数的值都会从容器中确定:
public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties,
// 找 Spring 的 beanFactory
ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
// 找到资源处理器的自定义器
ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
ObjectProvider<DispatcherServletPath> dispatcherServletPath,
// 给应用注册 Servlet,Fliter。。。
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();
}
2.1 资源处理默认规则
@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/");
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);
}
});
}
很多属性都可以在配置文件修改:
spring:
# mvc:
# static-path-pattern: /resources/**
web:
resources:
static-locations: [classpath:/public, classpath:/static]
add-mappings: true # 静态资源是否生效
cache:
period: 11000 # 静态资源缓存周期 单位: 秒