Web 场景

Spring MVC 自动配置

1、Spring Boot 为 Spring MVC 提供了自动配置,适用于大多数应用程序

2、自动配置在 Spring 的默认值之上添加了以下功能

(1)包含 ContentNegotiatingViewResolver(内容协商视图解析器)和 BeanNameViewResolver(BeanName 视图解析器)beans

(2)支持提供静态资源,包括对 WebJars 的支持

(3)自动注册 Converter、GenericConverter、Formatter beans

(4)支持 HttpMessageConverters

(5)自动注册 MessageCodesResolver(国际化)

(6)静态 index.html 支持

(7)自定义 Favicon 支持

(8)自动使用 ConfigurableWebBindingInitializer bean(DataBinder 负责将请求数据绑定到 JavaBean 上

3、定制化

(1)不使用 @EnableWebMvc,使用 @Configuration + WebMvcConfigurer 自定义规则:保留 Spring Boot MVC 功能,且添加额外 MVC 配置(拦截器,格式化程序,视图控制器和其他功能)

(2)声明 WebMvcRegistrations:改变默认底层组件,希望提供 RequestMappingHandlerMapping,RequestMappingHandlerAdapter 或 ExceptionHandlerExceptionResolver 的自定义实例

(3)使用 @EnableWebMvc + @Configuration + DelegatingWebMvcConfiguration:完全控制 Spring MVC

 

静态资源

1、目录

(1)默认情况下,Spring Boot 访问类路径中的 /static 或 /public 或 /resources 或 /META-INF/resources 目录或 ServletContext 的根目录中提供静态内容,它使用来自 Spring MVC 的 ResourceHttpRequestHandler,可以通过添加自己

WebMvcConfigurer,并覆盖 addResourceHandlers 方法来修改该行为

(2)默认静态资源目录:类路径下:/static 或 /public 或 /resources 或 /META-INF/resources

(3)改变默认的静态资源路径,使用 spring.resources.static-locations 属性自定义静态资源位置(将默认值替换为目录位置列表),根 Servlet 上下文路径"/"也会自动添加为位置

#静态资源存放在类路径下的new1目录、new2目录
spring:
  resources:
    static-locations: [classpath:/new/, calsspath:/new2/]

2、访问前缀

(1)默认情况下,无前缀,资源映射到 /**

(2)修改网页访问静态资源文件的路径,使用 spring.mvc.static-path-pattern 属性对其进行调整

#将所有资源重新定位到/resources/**
spring:
  mvc:
    static-path-pattern: /resources/**

3、访问:当前项目根路径/ + 静态资源名

4、原理:静态映射/**

5、接收请求,先使用 Controller 处理,不能处理的所有请求都交给静态资源处理器,无法查找静态资源,则响应 404 页面

 

欢迎页支持

1、Spring Boot 支持静态和模板化的欢迎页面,首先在配置的静态内容位置中查找 index.html 文件,如果找不到,则会查找 index 模板,如果找到任何一个,将自动用作应用程序的欢迎页面

2、两种欢迎页面

(1)静态资源路径下 index.html

(2)自定义 controller 处理 /index 请求

3、可以配置静态资源路径,或配置静态资源的访问前缀;若同时配置,则导致 index.html 不能被默认访问

 

自定义 Favicon

1、Spring Boot 在配置的静态内容位置和类路径的根(按此顺序)中查找 favicon.ico,如果存在这样的文件,它将自动用作应用程序的 favicon

2、欢迎页的自定义图标,必须命名为 favicon,类型为 ico

 

静态资源配置原理

1、SpringMVC 功能的自动配置类 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)
public class WebMvcAutoConfiguration {
    
}

2、WebMvcAutoConfigurationAdapter 是 WebMvcAutoConfiguration 的静态内部类

@Configuration(proxyBeanMethods = false)
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware{
    
    private final Resources resourceProperties;
    
    /*
        若配置类只有一个有参构造器,其中所有参数的值都会从容器中确定
        webProperties;获取和spring.web绑定的所有的值的对象
        mvcProperties:获取和spring.mvc绑定的所有的值的对象
        beanFactory:Spring的容器
        messageConvertersProvider:找到所有的HttpMessageConverters
        resourceHandlerRegistrationCustomizerProvider:找到资源处理器的自定义器
        dispatcherServletPath:DispatcherServlet处理路径
        servletRegistrations:给应用注册原生Servlet、Filter、Listener
    */
    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 addResourceHandlers(ResourceHandlerRegistry registry) {
        //addMappings默认为true;若为false,则禁用静态资源路径映射
        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);
            }
        });
    }
}

(1)配置文件的相关属性进行绑定

@ConfigurationProperties("spring.web")
public class WebProperties {

    public static class Resources {
        
        private boolean addMappings = true;
    }
}
@ConfigurationProperties(prefix = "spring.mvc")
public class WebMvcProperties

(2)禁用所有静态资源规则

spring:
  resources:
    add-mappings: false

3、EnableWebMvcConfiguration 是 WebMvcAutoConfiguration 的静态内部类

(1)HandlerMapping:SpringMVC 核心组件,处理器映射,保存每一个 Handler 对应的可处理请求

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebProperties.class)
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
    
    //欢迎页的处理规则
    @Bean
    public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
                                                               FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
        WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
            new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
            //从properties / yaml配置文件中,获取spring.mvc.static-path-pattern属性
            this.mvcProperties.getStaticPathPattern());
        welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
        welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
        return welcomePageHandlerMapping;
    }
}
final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping {

    WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
                              ApplicationContext applicationContext, Resource welcomePage, String staticPathPattern) {
        //欢迎页不为null,且路径必须为/**,才启用欢迎页
        if (welcomePage != null && "/**".equals(staticPathPattern)) {
            logger.info("Adding welcome page: " + welcomePage);
            setRootViewName("forward:index.html");
        }
        //否则调用Controller,进入/index
        else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
            logger.info("Adding welcome page template: index");
            setRootViewName("index");
        }
    }
}
posted @   半条咸鱼  阅读(23)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· 没有源码,如何修改代码逻辑?
· PowerShell开发游戏 · 打蜜蜂
· 在鹅厂做java开发是什么体验
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
点击右上角即可分享
微信分享提示