「SpringBoot3 Web开发」 WebMvcAutoConfiguration原理

1. 生效条件

// 我的自动配置类在这些自动配置之后配置
@AutoConfiguration(
	after = { 
		DispatcherServletAutoConfiguration.class, 
		TaskExecutionAutoConfiguration.class,
		ValidationAutoConfiguration.class 
	}) 
	
// 如果是web应用就生效,类型SERVLET、REACTIVE 响应式web
@ConditionalOnWebApplication(type = Type.SERVLET)

// 容器中没有这个Bean,才生效。默认就是没有
@ConditionalOnClass({ 
	Servlet.class, 
	DispatcherServlet.class,
	WebMvcConfigurer.class 
	})
// 容器中没有WebMvcConfigurationSupport类,才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class) 

// 优先级
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)

// 导入运行时的指标统计
@ImportRuntimeHints(WebResourcesRuntimeHints.class)
public class WebMvcAutoConfiguration { 
}

2. 效果

  1. 放了两个Filter:

    1. HiddenHttpMethodFilter;页面表单提交Rest请求(GET、POST、PUT、DELETE)
    2. FormContentFilter:表单内容Filter
      • GET(数据放URL后面)
      • POST(数据放请求体)请求可以携带数据
      • PUT、DELETE 的请求体数据会被忽略

  2. 给容器中放了WebMvcConfigurer组件;给SpringMVC添加各种定制功能

    1. 所有的功能最终会和配置文件进行绑定
    2. WebMvcPropertiesspring.mvc配置文件
    3. WebPropertiesspring.web配置文件
    	@Configuration(proxyBeanMethods = false)
    	@Import(EnableWebMvcConfiguration.class) // 额外导入了其他配置
    	@EnableConfigurationProperties({ WebMvcProperties.class, WebProperties.class })
    	@Order(0)
    	public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ServletContextAware{
            
        }
    

3. WebMvcConfigurer接口

提供了配置SpringMVC底层的所有组件入口image.png

4. 静态资源规则源码

@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
    if (!this.resourceProperties.isAddMappings()) {
        logger.debug("Default resource handling disabled");
        return;
    }
    // 1. 规则一
    addResourceHandler(
    	registry, this.mvcProperties.getWebjarsPathPattern(),
        "classpath:/META-INF/resources/webjars/"
    );
    // 2. 规则二
    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. 规则一:访问: /webjars/**路径就去 classpath:/META-INF/resources/webjars/下找资源.
    1. maven 导入依赖
      <dependency>
          <groupId>org.webjars.npm</groupId>
          <artifactId>ant-design__icons-vue</artifactId>
          <version>7.0.1</version>
      </dependency>
      
  2. 规则二:访问: /**路径就去 静态资源默认的四个位置找资源
    1. classpath:/META-INF/resources/
    2. classpath:/resources/
    3. classpath:/static/
    4. classpath:/public/
  3. 规则三:静态资源默认都有缓存规则的设置
    1. 所有缓存的设置,直接通过配置文件spring.web
    2. cachePeriod:缓存周期;多久不用找服务器要新的。 默认没有,以s为单位
    3. cacheControl HTTP缓存控制;https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Caching
    4. useLastModified:是否使用最后一次修改。配合HTTP Cache规则

如果浏览器访问了一个静态资源index.js,如果服务这个资源没有发生变化,下次访问的时候就可以直接让浏览器用自己缓存中的东西,而不用给服务器发请求。

registration.setCachePeriod(getSeconds(this.resourceProperties.getCache().getPeriod()));
registration.setCacheControl(this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl());
registration.setUseLastModified(this.resourceProperties.getCache().isUseLastModified());

5. EnableWebMvcConfiguration 源码

// SpringBoot 给容器中放 WebMvcConfigurationSupport 组件。
// 我们如果自己放了 WebMvcConfigurationSupport 组件,Boot的WebMvcAutoConfiguration都会失效。
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(WebProperties.class)
public static class EnableWebMvcConfiguration 
		extends DelegatingWebMvcConfiguration implements ResourceLoaderAware 
{
}

  1. HandlerMapping:根据请求路径 /a 找那个handler能处理请求
    1. WelcomePageHandlerMapping
      1. 访问 /**路径下的所有请求,都在以前四个静态资源路径下找,欢迎页也一样
      2. index.html:只要静态资源的位置有一个 index.html页面,项目启动默认访问

6. 为什么容器中放一个WebMvcConfigurer就能配置底层行为

  1. WebMvcAutoConfiguration 是一个自动配置类,它里面有一个 EnableWebMvcConfiguration
  2. EnableWebMvcConfiguration继承与 DelegatingWebMvcConfiguration,这两个都生效
  3. DelegatingWebMvcConfiguration利用 DI 把容器中 所有 WebMvcConfigurer 注入进来
  4. 别人调用 DelegatingWebMvcConfiguration 的方法配置底层规则,而它调用所有 WebMvcConfigurer的配置底层方法。

7. WebMvcConfigurationSupport

提供了很多的默认设置。
判断系统中是否有相应的类:如果有,就加入相应的HttpMessageConverter

jackson2Present = ClassUtils.isPresent(
		"com.fasterxml.jackson.databind.ObjectMapper", classLoader) &&
		ClassUtils.isPresent("com.fasterxml.jackson.core.JsonGenerator", 
		classLoader
	);
jackson2XmlPresent = ClassUtils.isPresent(
		"com.fasterxml.jackson.dataformat.xml.XmlMapper", classLoader
	);
jackson2SmilePresent = ClassUtils.isPresent(
		"com.fasterxml.jackson.dataformat.smile.SmileFactory", classLoader
	);
  • 19
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值