1、SpringBoot 启动默认加载 xxxAutoConfiguration 类(自动配置类)
2、SpringMVC 功能的自动配置类 WebMvcAutoConfiguration 生效

  1. @Configuration(proxyBeanMethods = false)
  2. @ConditionalOnWebApplication(type = Type.SERVLET)
  3. @ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
  4. @ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
  5. @AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
  6. @AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
  7. ValidationAutoConfiguration.class })
  8. public class WebMvcAutoConfiguration {}

给容器中配了什么?

  1. @Configuration(proxyBeanMethods = false)
  2. @Import(EnableWebMvcConfiguration.class)
  3. @EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
  4. @Order(0)
  5. public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {}

配置文件的相关属性和xxx进行了绑定。
WebMvcProperties==spring.mvc
ResourceProperties==spring.resources


扩展知识

配置类如果只有一个有参构造器

如果配置类只有一个有参构造器,那么有参构造器所有参数的值都会从容器中确定。

  1. //ResourceProperties resourceProperties;获取和spring.resources绑定的所有的值的对象
  2. //WebMvcProperties mvcProperties 获取和spring.mvc绑定的所有的值的对象
  3. //ListableBeanFactory beanFactory Spring的beanFactory
  4. //HttpMessageConverters 找到所有的HttpMessageConverters
  5. //ResourceHandlerRegistrationCustomizer 找到资源处理器的自定义器。
  6. //DispatcherServletPath
  7. //ServletRegistrationBean 给应用注册Servlet、Filter....
  8. public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties,
  9. ListableBeanFactory beanFactory, ObjectProvider<HttpMessageConverters> messageConvertersProvider,
  10. ObjectProvider<ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider,
  11. ObjectProvider<DispatcherServletPath> dispatcherServletPath,
  12. ObjectProvider<ServletRegistrationBean<?>> servletRegistrations) {
  13. this.resourceProperties = resourceProperties;
  14. this.mvcProperties = mvcProperties;
  15. this.beanFactory = beanFactory;
  16. this.messageConvertersProvider = messageConvertersProvider;
  17. this.resourceHandlerRegistrationCustomizer = resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
  18. this.dispatcherServletPath = dispatcherServletPath;
  19. this.servletRegistrations = servletRegistrations;
  20. }

资源处理的默认规则

  1. @Override
  2. public void addResourceHandlers(ResourceHandlerRegistry registry) {
  3. if (!this.resourceProperties.isAddMappings()) {
  4. logger.debug("Default resource handling disabled");
  5. return;
  6. }
  7. Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
  8. CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
  9. //webjars的规则
  10. if (!registry.hasMappingForPattern("/webjars/**")) {
  11. customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
  12. .addResourceLocations("classpath:/META-INF/resources/webjars/")
  13. .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
  14. }
  15. //
  16. String staticPathPattern = this.mvcProperties.getStaticPathPattern();
  17. if (!registry.hasMappingForPattern(staticPathPattern)) {
  18. customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
  19. .addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
  20. .setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
  21. }
  22. }
  1. spring:
  2. # mvc:
  3. # static-path-pattern: /res/**
  4. resources:
  5. add-mappings: false 禁用所有静态资源规则
  1. @ConfigurationProperties(prefix = "spring.resources", ignoreUnknownFields = false)
  2. public class ResourceProperties {
  3. private static final String[] CLASSPATH_RESOURCE_LOCATIONS = { "classpath:/META-INF/resources/",
  4. "classpath:/resources/", "classpath:/static/", "classpath:/public/" };
  5. /**
  6. * Locations of static resources. Defaults to classpath:[/META-INF/resources/,
  7. * /resources/, /static/, /public/].
  8. */
  9. private String[] staticLocations = CLASSPATH_RESOURCE_LOCATIONS;

欢迎页的处理规则

  1. HandlerMapping:处理器映射。保存了每一个Handler能处理哪些请求。
  2. @Bean
  3. public WelcomePageHandlerMapping welcomePageHandlerMapping(ApplicationContext applicationContext,
  4. FormattingConversionService mvcConversionService, ResourceUrlProvider mvcResourceUrlProvider) {
  5. WelcomePageHandlerMapping welcomePageHandlerMapping = new WelcomePageHandlerMapping(
  6. new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),
  7. this.mvcProperties.getStaticPathPattern());
  8. welcomePageHandlerMapping.setInterceptors(getInterceptors(mvcConversionService, mvcResourceUrlProvider));
  9. welcomePageHandlerMapping.setCorsConfigurations(getCorsConfigurations());
  10. return welcomePageHandlerMapping;
  11. }
  12. WelcomePageHandlerMapping(TemplateAvailabilityProviders templateAvailabilityProviders,
  13. ApplicationContext applicationContext, Optional<Resource> welcomePage, String staticPathPattern) {
  14. if (welcomePage.isPresent() && "/**".equals(staticPathPattern)) {
  15. //要用欢迎页功能,必须是/**
  16. logger.info("Adding welcome page: " + welcomePage.get());
  17. setRootViewName("forward:index.html");
  18. }
  19. else if (welcomeTemplateExists(templateAvailabilityProviders, applicationContext)) {
  20. // 调用Controller /index
  21. logger.info("Adding welcome page template: index");
  22. setRootViewName("index");
  23. }
  24. }