说在前面web
本次介绍MvcNamespaceHandler。关注“天河聊架构”更多源码解析。spring
springmvc配置解析跨域
@EnableWebMvc这个注解干了什么,初始化viewControllerHandlerMapping,初始化BeanNameUrlHandlerMapping,初始化resourceHandlerMapping缓存
进入到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#viewControllerHandlerMapping服务器
@Bean public HandlerMapping viewControllerHandlerMapping() { // 注册viewControllerHandlerMapping,建立ViewControllerRegistry ViewControllerRegistry registry = new ViewControllerRegistry(this.applicationContext); // 添加ViewControllers -》 addViewControllers(registry); // 构建HandlerMapping -》 AbstractHandlerMapping handlerMapping = registry.buildHandlerMapping(); handlerMapping = (handlerMapping != null ? handlerMapping : new EmptyHandlerMapping()); // 设置路径匹配器 -》 handlerMapping.setPathMatcher(mvcPathMatcher()); // 设置url路径解析器 handlerMapping.setUrlPathHelper(mvcUrlPathHelper()); // 设置拦截器 handlerMapping.setInterceptors(getInterceptors()); // 设置跨域配置 handlerMapping.setCorsConfigurations(getCorsConfigurations()); return handlerMapping; }
进入到这个方法org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#addViewControllers架构
@Override protected void addViewControllers(ViewControllerRegistry registry) { this.configurers.addViewControllers(registry); }
往上返回到这个方法org.springframework.web.servlet.config.annotation.ViewControllerRegistry#buildHandlerMappingmvc
protected SimpleUrlHandlerMapping buildHandlerMapping() { if (this.registrations.isEmpty() && this.redirectRegistrations.isEmpty()) { return null; } Map<String, Object> urlMap = new LinkedHashMap<String, Object>(); for (ViewControllerRegistration registration : this.registrations) { urlMap.put(registration.getUrlPath(), registration.getViewController()); } for (RedirectViewControllerRegistration registration : this.redirectRegistrations) { urlMap.put(registration.getUrlPath(), registration.getViewController()); } // 建立SimpleUrlHandlerMapping SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); handlerMapping.setUrlMap(urlMap); handlerMapping.setOrder(this.order); return handlerMapping; }
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#mvcPathMatcherapp
@Bean public PathMatcher mvcPathMatcher() { PathMatcher pathMatcher = getPathMatchConfigurer().getPathMatcher(); return (pathMatcher != null ? pathMatcher : new AntPathMatcher()); }
进入到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getPathMatchConfigurercors
protected PathMatchConfigurer getPathMatchConfigurer() { if (this.pathMatchConfigurer == null) { this.pathMatchConfigurer = new PathMatchConfigurer(); configurePathMatch(this.pathMatchConfigurer); } return this.pathMatchConfigurer; }
进入到这个方法org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#configurePathMatchide
@Override protected void configurePathMatch(PathMatchConfigurer configurer) { this.configurers.configurePathMatch(configurer); }
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#mvcUrlPathHelper
@Bean public UrlPathHelper mvcUrlPathHelper() { UrlPathHelper pathHelper = getPathMatchConfigurer().getUrlPathHelper(); return (pathHelper != null ? pathHelper : new UrlPathHelper()); }
进入到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getPathMatchConfigurer
protected PathMatchConfigurer getPathMatchConfigurer() { if (this.pathMatchConfigurer == null) { this.pathMatchConfigurer = new PathMatchConfigurer(); configurePathMatch(this.pathMatchConfigurer); } return this.pathMatchConfigurer; }
进入到这个方法org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#configurePathMatch
@Override protected void configurePathMatch(PathMatchConfigurer configurer) { this.configurers.configurePathMatch(configurer); }
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getInterceptors
protected final Object[] getInterceptors() { if (this.interceptors == null) { // 建立拦截器注册器 InterceptorRegistry registry = new InterceptorRegistry(); // mvc配置器添加拦截器注册器 addInterceptors(registry); // 添加ConversionServiceExposingInterceptor 拦截器 -》 registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService())); // 添加ResourceUrlProviderExposingInterceptor 拦截器 -》 registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider())); // 从拦截器注册器中获取拦截器 -》 this.interceptors = registry.getInterceptors(); } return this.interceptors.toArray(); }
这里前面介绍过了。
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getCorsConfigurations
protected final Map<String, CorsConfiguration> getCorsConfigurations() { if (this.corsConfigurations == null) { // 初始化跨域注册器 CorsRegistry registry = new CorsRegistry(); // 添加跨域映射 -》 addCorsMappings(registry); // 获取跨域配置 -》 this.corsConfigurations = registry.getCorsConfigurations(); } return this.corsConfigurations; }
这里前面介绍过了。
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#viewControllerHandlerMapping
进入到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#beanNameHandlerMapping
@Bean public BeanNameUrlHandlerMapping beanNameHandlerMapping() { // 建立BeanNameUrlHandlerMapping BeanNameUrlHandlerMapping mapping = new BeanNameUrlHandlerMapping(); mapping.setOrder(2); // 设置拦截器 mapping.setInterceptors(getInterceptors()); // 设置跨域配置 mapping.setCorsConfigurations(getCorsConfigurations()); return mapping; }
进入到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getInterceptors
protected final Object[] getInterceptors() { if (this.interceptors == null) { // 建立拦截器注册器 InterceptorRegistry registry = new InterceptorRegistry(); // mvc配置器添加拦截器注册器 addInterceptors(registry); // 添加ConversionServiceExposingInterceptor 拦截器 -》 registry.addInterceptor(new ConversionServiceExposingInterceptor(mvcConversionService())); // 添加ResourceUrlProviderExposingInterceptor 拦截器 -》 registry.addInterceptor(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider())); // 从拦截器注册器中获取拦截器 -》 this.interceptors = registry.getInterceptors(); } return this.interceptors.toArray(); }
这里前面介绍过了。
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getCorsConfigurations
protected final Map<String, CorsConfiguration> getCorsConfigurations() { if (this.corsConfigurations == null) { // 初始化跨域注册器 CorsRegistry registry = new CorsRegistry(); // 添加跨域映射 -》 addCorsMappings(registry); // 获取跨域配置 -》 this.corsConfigurations = registry.getCorsConfigurations(); } return this.corsConfigurations; }
这里前面介绍过了。
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#beanNameHandlerMapping
进入到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#resourceHandlerMapping
@Bean public HandlerMapping resourceHandlerMapping() { // 初始化resourceHandlerMapping Assert.state(this.applicationContext != null, "No ApplicationContext set"); Assert.state(this.servletContext != null, "No ServletContext set"); // 建立ResourceHandlerRegistry -》 ResourceHandlerRegistry registry = new ResourceHandlerRegistry(this.applicationContext, this.servletContext, mvcContentNegotiationManager(), mvcUrlPathHelper()); // 给资源handler配置器添加资源handler注册器 -》 addResourceHandlers(registry); // 获取handlerMapping -》 AbstractHandlerMapping handlerMapping = registry.getHandlerMapping(); if (handlerMapping != null) { // 设置路径匹配器 handlerMapping.setPathMatcher(mvcPathMatcher()); // 设置url路径匹配器 handlerMapping.setUrlPathHelper(mvcUrlPathHelper()); // 设置url服务拦截器 -》 handlerMapping.setInterceptors(new ResourceUrlProviderExposingInterceptor(mvcResourceUrlProvider())); // 设置跨域 handlerMapping.setCorsConfigurations(getCorsConfigurations()); } else { handlerMapping = new EmptyHandlerMapping(); } return handlerMapping; }
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#mvcContentNegotiationManager
@Bean public ContentNegotiationManager mvcContentNegotiationManager() { if (this.contentNegotiationManager == null) { // 初始化媒体类型管理器 ContentNegotiationConfigurer configurer = new ContentNegotiationConfigurer(this.servletContext); // 设置默认类型 -》 configurer.mediaTypes(getDefaultMediaTypes()); // 配置媒体类型管理器 -》 configureContentNegotiation(configurer); // 构建媒体类型管理器 -》 this.contentNegotiationManager = configurer.buildContentNegotiationManager(); } return this.contentNegotiationManager; }
这里前面介绍过了。
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#mvcUrlPathHelper
@Bean public UrlPathHelper mvcUrlPathHelper() { UrlPathHelper pathHelper = getPathMatchConfigurer().getUrlPathHelper(); return (pathHelper != null ? pathHelper : new UrlPathHelper()); }
这里前面介绍过了。
往上返回到这个方法org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration#addResourceHandlers
@Override protected void addResourceHandlers(ResourceHandlerRegistry registry) { this.configurers.addResourceHandlers(registry); }
往上返回到这个方法org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry#getHandlerMapping
protected AbstractHandlerMapping getHandlerMapping() { if (this.registrations.isEmpty()) { return null; } Map<String, HttpRequestHandler> urlMap = new LinkedHashMap<String, HttpRequestHandler>(); for (ResourceHandlerRegistration registration : this.registrations) { for (String pathPattern : registration.getPathPatterns()) { // 获取ResourceHttpRequestHandler -》 ResourceHttpRequestHandler handler = registration.getRequestHandler(); if (this.pathHelper != null) { handler.setUrlPathHelper(this.pathHelper); } if (this.contentNegotiationManager != null) { handler.setContentNegotiationManager(this.contentNegotiationManager); } handler.setServletContext(this.servletContext); handler.setApplicationContext(this.applicationContext); try { // ResourceHttpRequestHandler加载配置 handler.afterPropertiesSet(); } catch (Throwable ex) { throw new BeanInitializationException("Failed to init ResourceHttpRequestHandler", ex); } urlMap.put(pathPattern, handler); } } // 建立SimpleUrlHandlerMapping SimpleUrlHandlerMapping handlerMapping = new SimpleUrlHandlerMapping(); handlerMapping.setOrder(order); handlerMapping.setUrlMap(urlMap); return handlerMapping; }
进入到这个方法org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration#getRequestHandler
protected ResourceHttpRequestHandler getRequestHandler() { // 建立ResourceHttpRequestHandler ResourceHttpRequestHandler handler = new ResourceHttpRequestHandler(); if (this.resourceChainRegistration != null) { // 设置ResourceResolvers -》 handler.setResourceResolvers(this.resourceChainRegistration.getResourceResolvers()); // 设置资源转换器 -》 handler.setResourceTransformers(this.resourceChainRegistration.getResourceTransformers()); } // 设置缓存相关属性 handler.setLocationValues(this.locationValues); if (this.cacheControl != null) { handler.setCacheControl(this.cacheControl); } else if (this.cachePeriod != null) { handler.setCacheSeconds(this.cachePeriod); } return handler; }
进入到这个方法org.springframework.web.servlet.config.annotation.ResourceChainRegistration#getResourceResolvers
protected List<ResourceResolver> getResourceResolvers() { if (!this.hasPathResolver) { List<ResourceResolver> result = new ArrayList<ResourceResolver>(this.resolvers); if (isWebJarsAssetLocatorPresent && !this.hasWebjarsResolver) { // 建立WebJarsResourceResolver result.add(new WebJarsResourceResolver()); } // 添加PathResourceResolver result.add(new PathResourceResolver()); return result; } return this.resolvers; }
往上返回到这个方法org.springframework.web.servlet.config.annotation.ResourceChainRegistration#getResourceTransformers
protected List<ResourceTransformer> getResourceTransformers() { if (this.hasVersionResolver && !this.hasCssLinkTransformer) { List<ResourceTransformer> result = new ArrayList<ResourceTransformer>(this.transformers); boolean hasTransformers = !this.transformers.isEmpty(); boolean hasCaching = hasTransformers && this.transformers.get(0) instanceof CachingResourceTransformer; result.add(hasCaching ? 1 : 0, new CssLinkResourceTransformer()); return result; } return this.transformers; }
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#mvcResourceUrlProvider
@Bean public ResourceUrlProvider mvcResourceUrlProvider() { // 初始化资源url服务器 ResourceUrlProvider urlProvider = new ResourceUrlProvider(); // 获取url路径解析器 -》 UrlPathHelper pathHelper = getPathMatchConfigurer().getUrlPathHelper(); if (pathHelper != null) { urlProvider.setUrlPathHelper(pathHelper); } PathMatcher pathMatcher = getPathMatchConfigurer().getPathMatcher(); if (pathMatcher != null) { urlProvider.setPathMatcher(pathMatcher); } return urlProvider; }
进入到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#getPathMatchConfigurer
protected PathMatchConfigurer getPathMatchConfigurer() { if (this.pathMatchConfigurer == null) { this.pathMatchConfigurer = new PathMatchConfigurer(); configurePathMatch(this.pathMatchConfigurer); } return this.pathMatchConfigurer; }
这里前面介绍过了。
往上返回到这个方法org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport#resourceHandlerMapping
说到最后
本次源码解析仅表明我的观点,仅供参考。