SpringBoot实战(八)Web开发之静态资源处理

文档地址

https://docs.spring.io/spring-boot/docs/2.3.4.RELEASE/reference/html/spring-boot-features.html#boot-features-spring-mvc-static-content

静态资源目录及访问

(1)静态资源目录

By default, Spring Boot serves static content from a directory called /static (or /public or /resources or /META-INF/resources) in the classpath or from the root of the ServletContext. It uses the ResourceHttpRequestHandler from Spring MVC so that you can modify that behavior by adding your own WebMvcConfigurer and overriding the addResourceHandlers method.

大意:默认情况下,Spring Boot服务的静态内容来自类路径中的/static(或/public或/resources或/META-INF/resources)目录,或者来自ServletContext的根目录。它使用了来自Spring MVC的ResourceHttpRequestHandler,这样你就可以通过添加你自己的WebMvcConfigurer和覆盖addResourceHandlers方法来修改该行为。

By default, resources are mapped on /, but you can tune that with the spring.mvc.static-path-pattern property. For instance, relocating all resources to /resources/ can be achieved as follows:

大意:默认情况下,资源映射到/**上,但是你可以使用spring.mvc对其进行调优。static-path-pattern财产。例如,重新定位所有资源到/resources/**可以实现如下:

spring.mvc.static-path-pattern=/resources/**

By default, resources are mapped on /, but you can tune that with the spring.mvc.static-path-pattern property. For instance, relocating all resources to /resources/ can be achieved as follows:

大意:您还可以使用spring.resources自定义静态资源位置。Static-locations属性(用目录位置列表替换默认值)。根Servlet上下文路径“/”也会自动添加为一个位置。

注意:spring.mvc.static-locations 已过期,用下面这个。

spring:
  web:
    resources:
      static-locations:

(2)访问
使用默认的静态资源访问规则:
访问:只要资源放在上面对应的路径中,则 当前项目根路径/+静态资源名
原理:请求进来,先去找Controller看能不能处理。不能处理的所有请求又都交给静态资源处理器。如果静态资源也找不到,则报404.

如果自定义了静态资源的位置则:
访问路径:当前项目+ static-path-pattern+静态资源名称

在SpringBoot中的配置原理

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 {

WebMvcAutoConfigurationAdapter:

@Configuration(proxyBeanMethods = false)
	@Import(EnableWebMvcConfiguration.class)
	@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
	@Order(0)
	public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {

一共涉及到两个Properties类:

@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties {
@ConfigurationProperties("spring.web")
public class WebProperties {

WebMvcAutoConfigurationAdapter 配置类中有一个构造函数如下:

//有参构造器的所有参数都会从容器中确定
// WebProperties
// WebMvcProperties 获取所有和spring.mvc绑定的所有的值的对象
// ListableBeanFactory beanFactory   Spring的beanFactory
// ObjectProvider<HttpMessageConverters> messageConvertersProvider  找到所有的HttpMessageConverters
//ResourceHandlerRegistrationCustomizer 找到 资源处理器的自定义器
// dispatcherServletPath
// servletRegistrations
 public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware {
        private static final Log logger = LogFactory.getLog(WebMvcConfigurer.class);
        private final Resources resourceProperties;
        private final WebMvcProperties mvcProperties;
        private final ListableBeanFactory beanFactory;
        private final ObjectProvider<HttpMessageConverters> messageConvertersProvider;
        private final ObjectProvider<DispatcherServletPath> dispatcherServletPath;
        private final ObjectProvider<ServletRegistrationBean<?>> servletRegistrations;
        private final WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
        private ServletContext servletContext;

        public WebMvcAutoConfigurationAdapter(WebProperties webProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, ObjectProvider<DispatcherServletPath> dispatcherServletPath, ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
            this.resourceProperties = webProperties.getResources();
            this.mvcProperties = mvcProperties;
            this.beanFactory = beanFactory;
            this.messageConvertersProvider = messageConvertersProvider;
            this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
            this.dispatcherServletPath = dispatcherServletPath;
            this.servletRegistrations = servletRegistrations;
            this.mvcProperties.checkConfiguration();
        }

静态资源的默认处理规则:

public void addResourceHandlers(ResourceHandlerRegistry registry) {
            if (!this.resourceProperties.isAddMappings()) {
                logger.debug("Default resource handling disabled");
            } else {
                this.addResourceHandler(registry, "/webjars/**", "classpath:/META-INF/resources/webjars/");
                this.addResourceHandler(registry, this.mvcProperties.getStaticPathPattern(), (registration) -> {
                    registration.addResourceLocations(this.resourceProperties.getStaticLocations());
                    if (this.servletContext != null) {
                        ServletContextResource resource = new ServletContextResource(this.servletContext, "/");
                        registration.addResourceLocations(new Resource[]{resource});
                    }

                });
            }
        }

有一个方法:

registration.addResourceLocations(this.resourceProperties.getStaticLocations());

找到一个私有的数组:就是内置的静态资源路径

  public static class Resources {
        private static final String[] CLASSPATH_RESOURCE_LOCATIONS = new String[]{"classpath:/META-INF/resources/", "classpath:/resources/", "classpath:/static/", "classpath:/public/"};
        private String[] staticLocations;
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值