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; }