說在前面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
說到最後
本次源碼解析僅表明我的觀點,僅供參考。