2.0.2.RELEASEhtml
如下是SpringBoot對SpringMVC的默認配置:(WebMvcAutoConfiguration) Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans. 自動配置了ViewResolver(視圖解析器:根據方法的返回值獲得視圖對象(View),視圖對象決定如何 渲染(轉發?重定向?)) ContentNegotiatingViewResolver:組合全部的視圖解析器的; 如何定製:咱們能夠本身給容器中添加一個視圖解析器;自動的將其組合進來; Support for serving static resources, including support for WebJars (see below).靜態資源文件夾路 徑,webjars Static index.html support. 靜態首頁訪問 Custom Favicon support (see below). favicon.ico 自動註冊了 of Converter , GenericConverter , Formatter beans. Converter:轉換器; public String hello(User user):類型轉換使用Converter Formatter 格式化器; 2017.12.17===Date; 本身添加的格式化器轉換器,咱們只須要放在容器中便可 Support for HttpMessageConverters (see below). HttpMessageConverter:SpringMVC用來轉換Http請求和響應的;User---Json; HttpMessageConverters 是從容器中肯定;獲取全部的HttpMessageConverter; 本身給容器中添加HttpMessageConverter,只須要將本身的組件註冊容器中 (@Bean,@Component) Automatic registration of MessageCodesResolver (see below).定義錯誤代碼生成規則 Automatic use of a ConfigurableWebBindingInitializer bean (see below). 咱們能夠配置一個ConfigurableWebBindingInitializer來替換默認的;(添
@Bean @ConditionalOnMissingBean @ConditionalOnProperty(prefix = "spring.mvc", name = "locale") public LocaleResolver localeResolver() { if (this.mvcProperties .getLocaleResolver() == WebMvcProperties.LocaleResolver.FIXED) { return new FixedLocaleResolver(this.mvcProperties.getLocale()); } //默認用這個作本地化解析 AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver(); localeResolver.setDefaultLocale(this.mvcProperties.getLocale()); return localeResolver; } @Override public Locale resolveLocale(HttpServletRequest request) { Locale defaultLocale = getDefaultLocale(); //在使用本地化的時候是根據瀏覽器的語言決定用那種本地化的 if (defaultLocale != null && request.getHeader("Accept-Language") == null) { return defaultLocale; } }
//消息顯示格式 @Override public MessageCodesResolver getMessageCodesResolver() { if (this.mvcProperties.getMessageCodesResolverFormat() != null) { DefaultMessageCodesResolver resolver = new DefaultMessageCodesResolver(); resolver.setMessageCodeFormatter( this.mvcProperties.getMessageCodesResolverFormat()); return resolver; } return null; } //messageCodesResolverFormat 是Format 類型 private DefaultMessageCodesResolver.Format messageCodesResolverFormat; //而Format 其實是一個enum public enum Format implements MessageCodeFormatter { /** * 錯誤碼,對象名,字段 * {@code errorCode + "." + object name + "." + field} */ PREFIX_ERROR_CODE { @Override public String format(String errorCode, @Nullable String objectName, @Nullable String field) { return toDelimitedString(errorCode, objectName, field); } },
@Override public void addFormatters(FormatterRegistry registry) { //從容器中獲取轉換器 for (Converter<?, ?> converter : getBeansOfType(Converter.class)) { registry.addConverter(converter); } for (GenericConverter converter : getBeansOfType(GenericConverter.class)) { registry.addConverter(converter); } //從容器中獲取格式化器 for (Formatter<?> formatter : getBeansOfType(Formatter.class)) { registry.addFormatter(formatter); } } //也就是說若是咱們想自定義,只須要給容器加入對應的格式化器和轉換器便可,springboot會自動讓咱們配置的優先生效
//默認視圖解析器爲ContentNegotiatingViewResolver ,會從容器中拿到全部的視圖解析器 //若是能對應視圖解析器解析就返回解析結果 //咱們自定義的是視圖解析器只要加入容器就會生效 @Bean @ConditionalOnBean(ViewResolver.class) @ConditionalOnMissingBean(name = "viewResolver", value = ContentNegotiatingViewResolver.class) public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) { ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver(); resolver.setContentNegotiationManager( beanFactory.getBean(ContentNegotiationManager.class)); // ContentNegotiatingViewResolver uses all the other view resolvers to locate // a view so it should have a high precedence resolver.setOrder(Ordered.HIGHEST_PRECEDENCE); return resolver; }
//先從容器中獲取,獲取不到就利用父類獲取 @Override protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() { try { return this.beanFactory.getBean(ConfigurableWebBindingInitializer.class); } catch (NoSuchBeanDefinitionException ex) { return super.getConfigurableWebBindingInitializer(); } } //父類就new 一個ConfigurableWebBindingInitializer protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() { ConfigurableWebBindingInitializer initializer = new ConfigurableWebBindingInitializer(); //主要方法 @Override public void initBinder(WebDataBinder binder) { binder.setAutoGrowNestedPaths(this.autoGrowNestedPaths); if (this.directFieldAccess) { binder.initDirectFieldAccess(); } if (this.messageCodesResolver != null) { binder.setMessageCodesResolver(this.messageCodesResolver); } if (this.bindingErrorProcessor != null) { binder.setBindingErrorProcessor(this.bindingErrorProcessor); } if (this.validator != null && binder.getTarget() != null && this.validator.supports(binder.getTarget().getClass())) { binder.setValidator(this.validator); } if (this.conversionService != null) { binder.setConversionService(this.conversionService); } if (this.propertyEditorRegistrars != null) { for (PropertyEditorRegistrar propertyEditorRegistrar : this.propertyEditorRegistrars) { propertyEditorRegistrar.registerCustomEditors(binder); } } }
//這個就是對資源的映射 public void addResourceHandlers(ResourceHandlerRegistry registry) { if (!this.resourceProperties.isAddMappings()) { logger.debug("Default resource handling disabled"); return; } Duration cachePeriod = this.resourceProperties.getCache().getPeriod(); CacheControl cacheControl = this.resourceProperties.getCache() .getCachecontrol().toHttpCacheControl(); if (!registry.hasMappingForPattern("/webjars/**")) { //將/webjars/** 都定位到classpath:/META-INF/resources/webjars/ customizeResourceHandlerRegistration(registry .addResourceHandler("/webjars/**") .addResourceLocations("classpath:/META-INF/resources/webjars/") .setCachePeriod(getSeconds(cachePeriod)) .setCacheControl(cacheControl)); } //staticPathPattern 默認是 /** ,即全部請求 String staticPathPattern = this.mvcProperties.getStaticPathPattern(); if (!registry.hasMappingForPattern(staticPathPattern)) { customizeResourceHandlerRegistration( registry.addResourceHandler(staticPathPattern) //這些路徑咱們也叫靜態資源路徑,只要沒人處理就定位到此處 .addResourceLocations(getResourceLocations( this.resourceProperties.getStaticLocations())) .setCachePeriod(getSeconds(cachePeriod)) .setCacheControl(cacheControl)); } }
public WelcomePageHandlerMapping welcomePageHandlerMapping( ApplicationContext applicationContext) { return new WelcomePageHandlerMapping( new TemplateAvailabilityProviders(applicationContext), applicationContext, getWelcomePage(),//全部的靜態資源文件夾下的index.html this.mvcProperties.getStaticPathPattern());//被 /** 映射 }
public SimpleUrlHandlerMapping faviconHandlerMapping() { SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping(); mapping.setOrder(Ordered.HIGHEST_PRECEDENCE + 1); //將任意路徑的favicon.ico 映射到靜態資源文件夾下 mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", faviconRequestHandler())); return mapping; }