Spring Boot web原理

概述

Spring Boot应用通过依赖spring-boot-starter-web包,使我们能够快速构建web应用。模块默认引入了jackson、嵌入tomcat、spring-web和spring-webmvc。

原理

有三种方式实现webmvc配置

  1. 自动配置,项目通过引入了对应jar包,使的classpath路径下存在对应类,spring boot应用启动时通过扫描/META-INF/spring.factories文件中的WebMvcAutoConfiguration,完成web模块的引入。实现WebMvcConfigurer接口可增加自定义配置。
  2. 通过使用@EnableWebMvc注解和实现WebMvcConfigurer接口,完成自定义mvc配置
  3. 通过继承WebMvcConfigurationSupport类

自动配置

WebMvcAutoConfiguration

注解的含义

当application类型为servlet,classpath中存在Servlet、DispatcherServlet、WebMvcConfigurer类且不存在WebMvcConfigurationSupport类才装载该类到IOC容器中
在DispatcherServletAutoConfiguration、TaskExecutionAutoConfiguration和ValidationAutoConfiguration类引入之后导入

在WebMvcAutoConfiguration配置类中定义的内容如下

当HiddenHttpMethodFilter和FormContentFilter类不存在时且配置中存在spring.mvc.formcontent.filter为true,引入默认的OrderedHiddenHttpMethodFilter和OrderedFormContentFilter类
引入配置类WebMvcAutoConfigurationAdapter和EnableWebMvcConfiguration

@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{
	
	}
	
	@Configuration(proxyBeanMethods = false)
	public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware{
	
	}
	
	····
}
EnableWebMvcConfiguration

实现WebMvc默认配置,继承DelegatingWebMvcConfiguration类,通过@AutoWired注解加载beanFactory中的WebMvcConfigurer类型到WebMvcConfigurerComposite中
通过调用持有的WebMvcConfigurer中的方法,将对应mvc拓展设置注册到对应的mvc组件中,如调用WebMvcConfigurer的addInterceptors将拦截器注册到处理器映射器

注册默认RequestMappingHandlerAdapter、RequestMappingHandlerMapping到IOC容器
注册WelcomePageHandlerMapping到IOC容器,首页处理器映射器,默认为index,从资源路径中查询index.html文件
FormattingConversionService格式转换器
Validator验证器
ContentNegotiationManager内容协商管理,用于判断一个请求的媒体类型

WebMvcAutoConfigurationAdapter

注解内容:导入EnableWebMvcConfiguration类,启用WebMvcProperties(spring.mvc前缀)和ResourceProperties(spring.resources前缀)配置属性
InternalResourceViewResolver、BeanNameViewResolver注册视图解析器
ContentNegotiatingViewResolver内容协商解析器
LocaleResolver国际化解析
RequestContextFilter请求内容过滤器,将请求内容暴露给当前线程


在WebMvcAutoConfiguration中我们看到了注解@AutoConfigureAfter,表明DispatcherServletAutoConfiguration类会先于被解析

DispatcherServletAutoConfiguration

注解

当application类型为SERVLET且classpath中包含DispatcherServlet类时才加载
在ServletWebServerFactoryAutoConfiguration之后加载

内容

加载DispatcherServletConfiguration(初始dispatcherServlet和mutilpartResolver)和DispatcherServletRegistrationConfiguration配置类

@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass(DispatcherServlet.class)
@AutoConfigureAfter(ServletWebServerFactoryAutoConfiguration.class)
public class DispatcherServletAutoConfiguration {

	@Configuration(proxyBeanMethods = false)
	@Conditional(DefaultDispatcherServletCondition.class)
	@ConditionalOnClass(ServletRegistration.class)
	@EnableConfigurationProperties(WebMvcProperties.class)
	// classpath中存在ServletRegistration类且beanFactory中不存在dispatcherServlet类才加载
	protected static class DispatcherServletConfiguration {

		@Bean(name = DEFAULT_DISPATCHER_SERVLET_BEAN_NAME)
		public DispatcherServlet dispatcherServlet(WebMvcProperties webMvcProperties) {
			DispatcherServlet dispatcherServlet = new DispatcherServlet();
			dispatcherServlet.setDispatchOptionsRequest(webMvcProperties.isDispatchOptionsRequest());
			dispatcherServlet.setDispatchTraceRequest(webMvcProperties.isDispatchTraceRequest());
			dispatcherServlet.setThrowExceptionIfNoHandlerFound(webMvcProperties.isThrowExceptionIfNoHandlerFound());
			dispatcherServlet.setPublishEvents(webMvcProperties.isPublishRequestHandledEvents());
			dispatcherServlet.setEnableLoggingRequestDetails(webMvcProperties.isLogRequestDetails());
			return dispatcherServlet;
		}

		@Bean
		@ConditionalOnBean(MultipartResolver.class)
		@ConditionalOnMissingBean(name = DispatcherServlet.MULTIPART_RESOLVER_BEAN_NAME)
		// 当beanFactory中存在MultipartResolver类且不存在名为multipartResolver的bean
		public MultipartResolver multipartResolver(MultipartResolver resolver) {
			// Detect if the user has created a MultipartResolver but named it incorrectly
			return resolver;
		}

	}
}

在初始dispatcherServlet之前会先加载ServletWebServerFactoryAutoConfiguration配置类

ServletWebServerFactoryAutoConfiguration

注解内容:当application类型为SERVLET且存在ServletRequest类才加载
ServerProperties配置类定义了启动端口、最大http头等信息(前缀server.port)
通过BeanPostProcessorsRegistrar注入完成对WebServerFactoryCustomizerBeanPostProcessor和ErrorPageRegistrarBeanPostProcessor类注入

@Configuration(proxyBeanMethods = false)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
		ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
		ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
		ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
	
	// ServletWebServerFactory自定义器,通过传入serverProperties来定义ConfigurableServletWebServerFactory属性
	@Bean
	public ServletWebServerFactoryCustomizer servletWebServerFactoryCustomizer(ServerProperties serverProperties) {
		return new ServletWebServerFactoryCustomizer(serverProperties);
	}

	@Bean
	@ConditionalOnClass(name = "org.apache.catalina.startup.Tomcat")
	// 存在tomcat类时加载
	public TomcatServletWebServerFactoryCustomizer tomcatServletWebServerFactoryCustomizer(
			ServerProperties serverProperties) {
		return new TomcatServletWebServerFactoryCustomizer(serverProperties);
	}
}

@EnableWebMvc+WebMvcConfigurer

类继承图

在这里插入图片描述

在WebMvcAutoConfiguration的注解中存在@ConditionalOnMissingBean(WebMvcConfigurationSupport.class),说明如果BeanFactory中存在WebMvcConfigurationSupport对象则不自动进行mvc配置

@EnableWebMvc

导入了DelegatingWebMvcConfiguration类,其中自动装填了setConfigurers(List configurers)方法
DelegatingWebMvcConfiguration继承WebMvcConfigurationSupport类实现了RequestMappingHandlerMapping、HandlerExceptionResolver、ViewResolver及HttpRequestHandlerAdapter类的bean注册

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
WebMvcConfigurer

配置webMvc

public interface WebMvcConfigurer {
	// 帮助配置HandlerMappings路径匹配选项,例如尾部斜杠匹配、后缀注册、路径匹配器。
	// suffixPatternMatch默认true /hello -> 匹配 /hello.*
	// trailingSlashMatch默认true /hello -> 匹配 /hello/
	default void configurePathMatch(PathMatchConfigurer configurer) {
	}
	
	// 添加拦截器
	default void addInterceptors(InterceptorRegistry registry) {
	}
	
	// 跨域请求处理
	default void addCorsMappings(CorsRegistry registry) {
	}

	// 添加uri对应视图转换
	default void addViewControllers(ViewControllerRegistry registry) {
	}

	// 添加处理程序以服务于静态资源,自定义静态资源映射目录
	default void addResourceHandlers(ResourceHandlerRegistry registry) {
	}
}

WebMvcConfigurationSupport

通过实现该类完成mvc的配置,存在该类则spring boot自动配置不生效,在静态块中判断是否存在json转换器

public class WebMvcConfigurationSupport implements ApplicationContextAware, ServletContextAware {
	@Nullable
	private ApplicationContext applicationContext;

	@Nullable
	private ServletContext servletContext;

	@Nullable
	private List<Object> interceptors;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值