| |
| |
| |
| @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, ResourceProperties.class }) |
| @Order(0) |
| public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {} |
| |
| |
| |
| |
| |
| |
| |
| |
| public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, |
| ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider, |
| ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider, |
| ObjectProvider<DispatcherServletPath> dispatcherServletPath, |
| ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) { |
| this.resourceProperties = resourceProperties; |
| this.mvcProperties = mvcProperties; |
| this.beanFactory = beanFactory; |
| this.messageConvertersProvider = messageConvertersProvider; |
| this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable(); |
| this.dispatcherServletPath = dispatcherServletPath; |
| this.servletRegistrations = servletRegistrations; |
| } |
| @Override |
| public void addResourceHandlers(ResourceHandlerRegistry registry) { |
| if (!this.resourceProperties.isAddMappings()) { |
| logger.debug("Default resource handling disabled"); |
| return; |
| } |
| Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); |
| CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl(); |
| |
| if (!registry.hasMappingForPattern("/webjars/**")) { |
| customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**") |
| .addResourceLocations("classpath:/META-INF/resources/webjars/") |
| .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); |
| } |
| |
| |
| |
| String staticPathPattern = this.mvcProperties.getStaticPathPattern(); |
| if (!registry.hasMappingForPattern(staticPathPattern)) { |
| customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern) |
| .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations())) |
| .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl)); |
| } |
| } |
| spring: |
| resources: |
| add-mappings: false 禁用所有静态资源规则 |
- getResourceLocations(this.resourceProperties.getStaticLocations())的默认值如下
| @ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false) |
| public class ResourceProperties { |
| |
| private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/", |
| "classpath:/resources/", "classpath:/static/", "classpath:/public/" }; |
| |
| |
| |
| |
| |
| private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS; |
| # HandlerMapping:处理器映射。保存了每一个Handler能处理哪些请求。 |
| |
| @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方法 |
| WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders, |
| ApplicationContext applicationContext, Optional<Resource> welcomePage, String staticPathPattern) { |
| if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) { |
| |
| logger.info("Adding welcome page: " + welcomePage.get()); |
| setRootViewName("forward:index.html"); |
| } |
| |
| else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) { |
| |
| logger.info("Adding welcome page template: index"); |
| setRootViewName("index"); |
| } |
| } |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?