1、Spring mvc初始化时会创建哪些HandlerMapping
- requestMappingHandlerMapping,order为0,类型为RequestMappingHandlerMapping
- viewControllerHandlerMapping, order为1,类型为SimpleUrlHandlerMapping
- beanNameHandlerMapping, order为2,类型为BeanNameUrlHandlerMapping
- routerFunctionMapping,order为3,类型为RouterFunctionMapping
- resourceHandlerMapping,order为Integer.MAX_VALUE-1,类型为SimpleUrlHandlerMapping
- defaultServletHandlerMapping,order为Integer.MAX_VALUE,类型为SimpleUrlHandlerMapping
2、viewControllerHandlerMapping的创建
依赖ViewControllerRegistry来创建SimpleUrlHandlerMapping,同时预留扩展方法addViewControllers。根据PathMatchConfigurer来配置PatternParser或者PathMacher。设置拦截器及跨域配置
public HandlerMapping viewControllerHandlerMapping(
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
ViewControllerRegistry registry = new ViewControllerRegistry(this.applicationContext);
addViewControllers(registry);
AbstractHandlerMapping handlerMapping = registry.buildHandlerMapping();
if (handlerMapping == null) {
return null;
}
PathMatchConfigurer pathConfig = getPathMatchConfigurer();
if (pathConfig.getPatternParser() != null) {
handlerMapping.setPatternParser(pathConfig.getPatternParser());
}
else {
handlerMapping.setUrlPathHelper(pathConfig.getUrlPathHelperOrDefault());
handlerMapping.setPathMatcher(pathConfig.getPathMatcherOrDefault());
}
handlerMapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
handlerMapping.setCorsConfigurations(getCorsConfigurations());
return handlerMapping;
}
ViewControllerRegistry的结构如下:
依赖ViewControllerRegistration和RedirectViewControllerRegistration,通过addViewController创建ViewControllerRegistration添加到ViewControllerRegistry中的registrations列表中,通过addRedirectViewController创建RedirectViewControllerRegistration添加到ViewControllerRegistry中的redirectRegistrations列表中。buildHandlerMapping遍历registrations和redirectRegistrations来创建SimpleUrlHandlerMapping
protected SimpleUrlHandlerMapping buildHandlerMapping() {
if (this.registrations.isEmpty() && this.redirectRegistrations.isEmpty()) {
return null;
}
Map<String, Object> urlMap = new LinkedHashMap<>();
for (ViewControllerRegistration registration : this.registrations) {
urlMap.put(registration.getUrlPath(), registration.getViewController());
}
for (RedirectViewControllerRegistration registration : this.redirectRegistrations) {
urlMap.put(registration.getUrlPath(), registration.getViewController());
}
return new SimpleUrlHandlerMapping(urlMap, this.order);
}
3、beanNameHandlerMapping的创建
创建BeanNameUrlHandlerMapping。根据PathMatchConfigurer来配置PatternParser或者PathMacher。设置拦截器及跨域配置。
@Bean
public BeanNameUrlHandlerMapping beanNameHandlerMapping(
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping();
mapping.setOrder(2);
PathMatchConfigurer pathConfig = getPathMatchConfigurer();
if (pathConfig.getPatternParser() != null) {
mapping.setPatternParser(pathConfig.getPatternParser());
}
else {
mapping.setUrlPathHelper(pathConfig.getUrlPathHelperOrDefault());
mapping.setPathMatcher(pathConfig.getPathMatcherOrDefault());
}
mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
mapping.setCorsConfigurations(getCorsConfigurations());
return mapping;
}
4、routerFunctionMapping的创建
创建RouterFunctionMapping。设置拦截器及跨域配置,设置MessageConverters,同时设置PatternParser。
@Bean
public RouterFunctionMapping routerFunctionMapping(
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
RouterFunctionMapping mapping = new RouterFunctionMapping();
mapping.setOrder(3);
mapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
mapping.setCorsConfigurations(getCorsConfigurations());
mapping.setMessageConverters(getMessageConverters());
PathPatternParser patternParser = getPathMatchConfigurer().getPatternParser();
if (patternParser != null) {
mapping.setPatternParser(patternParser);
}
return mapping;
}
5、resourceHandlerMapping的创建
ResourceHandlerRegistry的结构为
依赖ResourceHandlerRegistry来创建SimpleUrlHandlerMapping,同时预留扩展方法addResourceHandlers。根据PathMatchConfigurer来配置PatternParser或者PathMacher。设置拦截器及跨域配置。
@Bean
@Nullable
public HandlerMapping resourceHandlerMapping(
@Qualifier("mvcContentNegotiationManager") ContentNegotiationManager contentNegotiationManager,
@Qualifier("mvcConversionService") FormattingConversionService conversionService,
@Qualifier("mvcResourceUrlProvider") ResourceUrlProvider resourceUrlProvider) {
Assert.state(this.applicationContext != null, "No ApplicationContext set");
Assert.state(this.servletContext != null, "No ServletContext set");
PathMatchConfigurer pathConfig = getPathMatchConfigurer();
ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext,
this.servletContext, contentNegotiationManager, pathConfig.getUrlPathHelper());
addResourceHandlers(registry);
AbstractHandlerMapping handlerMapping = registry.getHandlerMapping();
if (handlerMapping == null) {
return null;
}
if (pathConfig.getPatternParser() != null) {
handlerMapping.setPatternParser(pathConfig.getPatternParser());
}
else {
handlerMapping.setUrlPathHelper(pathConfig.getUrlPathHelperOrDefault());
handlerMapping.setPathMatcher(pathConfig.getPathMatcherOrDefault());
}
handlerMapping.setInterceptors(getInterceptors(conversionService, resourceUrlProvider));
handlerMapping.setCorsConfigurations(getCorsConfigurations());
return handlerMapping;
}
6、defaultServletHandlerMapping的创建
创建DefaultServletHandlerConfigurer,调用扩展方法configureDefaultServletHandling添加自定义的处理器。通过DefaultServletHandlerConfigurer的buildHandlerMapping创建SimpleUrlHandlerMapping。
@Bean
@Nullable
public HandlerMapping defaultServletHandlerMapping() {
Assert.state(this.servletContext != null, "No ServletContext set");
DefaultServletHandlerConfigurer configurer = new DefaultServletHandlerConfigurer(this.servletContext);
configureDefaultServletHandling(configurer);
return configurer.buildHandlerMapping();
}
DefaultServletHandlerConfigurer结构为
7 、拦截器管理
requestMappingHandlerMapping,viewControllerHandlerMapping,beanNameHandlerMapping,routerFunctionMapping,resourceHandlerMapping处理映射关系中会添加拦截器,包含用户自定的。默认会添加ConversionServiceExposingInterceptor,ResourceUrlProviderExposingInterceptor这两个拦截器
通过InterceptorRegistry来管理拦截器注册项InterceptorRegistration,InterceptorRegistration中包含拦截器,匹配模式includePattern,excluldePattern,以及pathMatcher。InterceptorRegistration在存在匹配模式时,返回的拦截器类型为MappedInterceptor。其结构如下