一:Spring Boot提供自動配置
經過查看WebMvcAutoConfiguration及WebMvcProperties的源碼,能夠發現Spring Boot爲咱們提供了以下的自動配置。html
1,自動配置的ViewResolver
1)ContentNegotiatingViewResolverjava
這是Spring MVC提供的一個特殊的ViewResolver,ContentNegotiatingViewResolver不是本身處理View,而是代理給不一樣的ViewResolver來處理不一樣的View,因此它有最高的優先級。web
2)BeanNameViewResolverspring
在控制器(@Controller)中的一個方法的返回值的字符串(視圖名)會根據 BeanNameViewResolver去查找Bean的名稱爲返回字符串的View來渲染視圖,下面舉個例子apache
定義BeanNameViewResolver的Beanjson
- @Bean
- public BeanNameViewResolver beanNameViewResolver(){
- BeanNameViewResolver resolver= new BeanNameViewResolver();
- return resolver
- }
定義一個View的Bean,名稱爲jsonViewmvc
- @Bean
- public MappingJackson2JsonView jsonView(){
- MappingJackson2JsonView jsonView = new MappingJackson2JsonView();
- return jsonView;
- }
在控制器中,返回值爲字符串jsonView,它會找Bean的名稱爲jsonView的視圖來渲染:app
- @RequestMapping(value = "json",produces = {MediaType.APPLICATION_JSON_VALUE})
- public String json(Model model){
- Person single = new Person("aa",11);
- model.addAttribute("single",single);
- return "jsonView";
- }
3)InternalResourceViewResolver框架
這是一個經常使用的ViewResolver,主要經過設置前綴,後綴,以及控制器中方法來返回視圖名的字符串,以獲得實際頁面,Spring Boot的源碼以下:jsp
- @Bean
- @ConditionalOnMissingBean
- public InternalResourceViewResolver defaultViewResolver() {
- InternalResourceViewResolver resolver = new InternalResourceViewResolver();
- resolver.setPrefix(this.mvcProperties.getView().getPrefix());
- resolver.setSuffix(this.mvcProperties.getView().getSuffix());
- return resolver;
- }
下面是WebMvcAutoConfiguration的源代碼:
-
- package org.springframework.boot.autoconfigure.web;
-
- import java.util.Collection;
- import java.util.Collections;
- import java.util.Date;
- import java.util.Iterator;
- import java.util.List;
- import java.util.ListIterator;
- import java.util.Map;
- import java.util.Map.Entry;
- import javax.servlet.Servlet;
- import javax.servlet.http.HttpServletRequest;
- import org.apache.commons.logging.Log;
- import org.apache.commons.logging.LogFactory;
- import org.springframework.beans.factory.BeanFactory;
- import org.springframework.beans.factory.ListableBeanFactory;
- import org.springframework.beans.factory.NoSuchBeanDefinitionException;
- import org.springframework.beans.factory.ObjectProvider;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.autoconfigure.AutoConfigureAfter;
- import org.springframework.boot.autoconfigure.AutoConfigureOrder;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnBean;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
- import org.springframework.boot.autoconfigure.condition.ConditionalOnWebApplication;
- import org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration;
- import org.springframework.boot.autoconfigure.web.ResourceProperties.Chain;
- import org.springframework.boot.autoconfigure.web.ResourceProperties.Strategy;
- import org.springframework.boot.context.properties.EnableConfigurationProperties;
- import org.springframework.boot.web.filter.OrderedHiddenHttpMethodFilter;
- import org.springframework.boot.web.filter.OrderedHttpPutFormContentFilter;
- import org.springframework.boot.web.filter.OrderedRequestContextFilter;
- import org.springframework.context.annotation.Bean;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Import;
- import org.springframework.context.annotation.Lazy;
- import org.springframework.context.annotation.Primary;
- import org.springframework.core.convert.converter.Converter;
- import org.springframework.core.convert.converter.GenericConverter;
- import org.springframework.core.io.Resource;
- import org.springframework.format.Formatter;
- import org.springframework.format.FormatterRegistry;
- import org.springframework.format.datetime.DateFormatter;
- import org.springframework.http.MediaType;
- import org.springframework.http.converter.HttpMessageConverter;
- import org.springframework.util.ClassUtils;
- import org.springframework.util.StringUtils;
- import org.springframework.validation.DefaultMessageCodesResolver;
- import org.springframework.validation.MessageCodesResolver;
- import org.springframework.validation.Validator;
- import org.springframework.web.HttpMediaTypeNotAcceptableException;
- import org.springframework.web.accept.ContentNegotiationManager;
- import org.springframework.web.accept.ContentNegotiationStrategy;
- import org.springframework.web.accept.PathExtensionContentNegotiationStrategy;
- import org.springframework.web.bind.support.ConfigurableWebBindingInitializer;
- import org.springframework.web.context.request.NativeWebRequest;
- import org.springframework.web.context.request.RequestContextListener;
- import org.springframework.web.filter.HiddenHttpMethodFilter;
- import org.springframework.web.filter.HttpPutFormContentFilter;
- import org.springframework.web.filter.RequestContextFilter;
- import org.springframework.web.servlet.DispatcherServlet;
- import org.springframework.web.servlet.HandlerExceptionResolver;
- import org.springframework.web.servlet.LocaleResolver;
- import org.springframework.web.servlet.View;
- import org.springframework.web.servlet.ViewResolver;
- import org.springframework.web.servlet.config.annotation.AsyncSupportConfigurer;
- import org.springframework.web.servlet.config.annotation.ContentNegotiationConfigurer;
- import org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration;
- import org.springframework.web.servlet.config.annotation.ResourceChainRegistration;
- import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistration;
- import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
- import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
- import org.springframework.web.servlet.handler.AbstractHandlerExceptionResolver;
- import org.springframework.web.servlet.handler.AbstractUrlHandlerMapping;
- import org.springframework.web.servlet.handler.SimpleUrlHandlerMapping;
- import org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver;
- import org.springframework.web.servlet.i18n.FixedLocaleResolver;
- import org.springframework.web.servlet.mvc.ParameterizableViewController;
- import org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver;
- import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
- import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
- import org.springframework.web.servlet.resource.AppCacheManifestTransformer;
- import org.springframework.web.servlet.resource.GzipResourceResolver;
- import org.springframework.web.servlet.resource.ResourceHttpRequestHandler;
- import org.springframework.web.servlet.resource.ResourceResolver;
- import org.springframework.web.servlet.resource.VersionResourceResolver;
- import org.springframework.web.servlet.view.BeanNameViewResolver;
- import org.springframework.web.servlet.view.ContentNegotiatingViewResolver;
- import org.springframework.web.servlet.view.InternalResourceViewResolver;
-
- @Configuration
- @ConditionalOnWebApplication
- @ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurerAdapter.class})
- @ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
- @AutoConfigureOrder(-2147483638)
- @AutoConfigureAfter({DispatcherServletAutoConfiguration.class, ValidationAutoConfiguration.class})
- public class WebMvcAutoConfiguration {
- public static final String DEFAULT_PREFIX = "";
- public static final String DEFAULT_SUFFIX = "";
-
- public WebMvcAutoConfiguration() {
- }
-
- @Bean
- @ConditionalOnMissingBean({HiddenHttpMethodFilter.class})
- public OrderedHiddenHttpMethodFilter hiddenHttpMethodFilter() {
- return new OrderedHiddenHttpMethodFilter();
- }
-
- @Bean
- @ConditionalOnMissingBean({HttpPutFormContentFilter.class})
- @ConditionalOnProperty(
- prefix = "spring.mvc.formcontent.putfilter",
- name = {"enabled"},
- matchIfMissing = true
- )
- public OrderedHttpPutFormContentFilter httpPutFormContentFilter() {
- return new OrderedHttpPutFormContentFilter();
- }
-
- static class OptionalPathExtensionContentNegotiationStrategy implements ContentNegotiationStrategy {
- private static final String SKIP_ATTRIBUTE = PathExtensionContentNegotiationStrategy.class.getName() + ".SKIP";
- private final ContentNegotiationStrategy delegate;
-
- OptionalPathExtensionContentNegotiationStrategy(ContentNegotiationStrategy delegate) {
- this.delegate = delegate;
- }
-
- public List<MediaType> resolveMediaTypes(NativeWebRequest webRequest) throws HttpMediaTypeNotAcceptableException {
- Object skip = webRequest.getAttribute(SKIP_ATTRIBUTE, 0);
- return skip != null && Boolean.parseBoolean(skip.toString()) ? Collections.emptyList() : this.delegate.resolveMediaTypes(webRequest);
- }
- }
-
- static final class WelcomePageHandlerMapping extends AbstractUrlHandlerMapping {
- private static final Log logger = LogFactory.getLog(WebMvcAutoConfiguration.WelcomePageHandlerMapping.class);
-
- private WelcomePageHandlerMapping(Resource welcomePage, String staticPathPattern) {
- if (welcomePage != null && "/**".equals(staticPathPattern)) {
- logger.info("Adding welcome page: " + welcomePage);
- ParameterizableViewController controller = new ParameterizableViewController();
- controller.setViewName("forward:index.html");
- this.setRootHandler(controller);
- this.setOrder(0);
- }
-
- }
-
- public Object getHandlerInternal(HttpServletRequest request) throws Exception {
- Iterator var2 = this.getAcceptedMediaTypes(request).iterator();
-
- MediaType mediaType;
- do {
- if (!var2.hasNext()) {
- return null;
- }
-
- mediaType = (MediaType)var2.next();
- } while(!mediaType.includes(MediaType.TEXT_HTML));
-
- return super.getHandlerInternal(request);
- }
-
- private List<MediaType> getAcceptedMediaTypes(HttpServletRequest request) {
- String acceptHeader = request.getHeader("Accept");
- return MediaType.parseMediaTypes(StringUtils.hasText(acceptHeader) ? acceptHeader : "*/*");
- }
- }
-
- private static class ResourceChainResourceHandlerRegistrationCustomizer implements WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer {
- @Autowired
- private ResourceProperties resourceProperties;
-
- private ResourceChainResourceHandlerRegistrationCustomizer() {
- this.resourceProperties = new ResourceProperties();
- }
-
- public void customize(ResourceHandlerRegistration registration) {
- Chain properties = this.resourceProperties.getChain();
- this.configureResourceChain(properties, registration.resourceChain(properties.isCache()));
- }
-
- private void configureResourceChain(Chain properties, ResourceChainRegistration chain) {
- Strategy strategy = properties.getStrategy();
- if (strategy.getFixed().isEnabled() || strategy.getContent().isEnabled()) {
- chain.addResolver(this.getVersionResourceResolver(strategy));
- }
-
- if (properties.isGzipped()) {
- chain.addResolver(new GzipResourceResolver());
- }
-
- if (properties.isHtmlApplicationCache()) {
- chain.addTransformer(new AppCacheManifestTransformer());
- }
-
- }
-
- private ResourceResolver getVersionResourceResolver(Strategy properties) {
- VersionResourceResolver resolver = new VersionResourceResolver();
- if (properties.getFixed().isEnabled()) {
- String version = properties.getFixed().getVersion();
- String[] paths = properties.getFixed().getPaths();
- resolver.addFixedVersionStrategy(version, paths);
- }
-
- if (properties.getContent().isEnabled()) {
- String[] paths = properties.getContent().getPaths();
- resolver.addContentVersionStrategy(paths);
- }
-
- return resolver;
- }
- }
-
- interface ResourceHandlerRegistrationCustomizer {
- void customize(ResourceHandlerRegistration var1);
- }
-
- @Configuration
- @ConditionalOnEnabledResourceChain
- static class ResourceChainCustomizerConfiguration {
- ResourceChainCustomizerConfiguration() {
- }
-
- @Bean
- public WebMvcAutoConfiguration.ResourceChainResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer() {
- return new WebMvcAutoConfiguration.ResourceChainResourceHandlerRegistrationCustomizer();
- }
- }
-
- @Configuration
- public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
- private final WebMvcProperties mvcProperties;
- private final ListableBeanFactory beanFactory;
- private final WebMvcRegistrations mvcRegistrations;
-
- public EnableWebMvcConfiguration(ObjectProvider<WebMvcProperties> mvcPropertiesProvider, ObjectProvider<WebMvcRegistrations> mvcRegistrationsProvider, ListableBeanFactory beanFactory) {
- this.mvcProperties = (WebMvcProperties)mvcPropertiesProvider.getIfAvailable();
- this.mvcRegistrations = (WebMvcRegistrations)mvcRegistrationsProvider.getIfUnique();
- this.beanFactory = beanFactory;
- }
-
- @Bean
- public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
- RequestMappingHandlerAdapter adapter = super.requestMappingHandlerAdapter();
- adapter.setIgnoreDefaultModelOnRedirect(this.mvcProperties == null ? true : this.mvcProperties.isIgnoreDefaultModelOnRedirect());
- return adapter;
- }
-
- protected RequestMappingHandlerAdapter createRequestMappingHandlerAdapter() {
- return this.mvcRegistrations != null && this.mvcRegistrations.getRequestMappingHandlerAdapter() != null ? this.mvcRegistrations.getRequestMappingHandlerAdapter() : super.createRequestMappingHandlerAdapter();
- }
-
- @Bean
- @Primary
- public RequestMappingHandlerMapping requestMappingHandlerMapping() {
- return super.requestMappingHandlerMapping();
- }
-
- @Bean
- public Validator mvcValidator() {
- return !ClassUtils.isPresent("javax.validation.Validator", this.getClass().getClassLoader()) ? super.mvcValidator() : WebMvcValidator.get(this.getApplicationContext(), this.getValidator());
- }
-
- protected RequestMappingHandlerMapping createRequestMappingHandlerMapping() {
- return this.mvcRegistrations != null && this.mvcRegistrations.getRequestMappingHandlerMapping() != null ? this.mvcRegistrations.getRequestMappingHandlerMapping() : super.createRequestMappingHandlerMapping();
- }
-
- protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
- try {
- return (ConfigurableWebBindingInitializer)this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
- } catch (NoSuchBeanDefinitionException var2) {
- return super.getConfigurableWebBindingInitializer();
- }
- }
-
- protected ExceptionHandlerExceptionResolver createExceptionHandlerExceptionResolver() {
- return this.mvcRegistrations != null && this.mvcRegistrations.getExceptionHandlerExceptionResolver() != null ? this.mvcRegistrations.getExceptionHandlerExceptionResolver() : super.createExceptionHandlerExceptionResolver();
- }
-
- protected void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
- super.configureHandlerExceptionResolvers(exceptionResolvers);
- if (exceptionResolvers.isEmpty()) {
- this.addDefaultHandlerExceptionResolvers(exceptionResolvers);
- }
-
- if (this.mvcProperties.isLogResolvedException()) {
- Iterator var2 = exceptionResolvers.iterator();
-
- while(var2.hasNext()) {
- HandlerExceptionResolver resolver = (HandlerExceptionResolver)var2.next();
- if (resolver instanceof AbstractHandlerExceptionResolver) {
- ((AbstractHandlerExceptionResolver)resolver).setWarnLogCategory(resolver.getClass().getName());
- }
- }
- }
-
- }
-
- @Bean
- public ContentNegotiationManager mvcContentNegotiationManager() {
- ContentNegotiationManager manager = super.mvcContentNegotiationManager();
- List<ContentNegotiationStrategy> strategies = manager.getStrategies();
- ListIterator iterator = strategies.listIterator();
-
- while(iterator.hasNext()) {
- ContentNegotiationStrategy strategy = (ContentNegotiationStrategy)iterator.next();
- if (strategy instanceof PathExtensionContentNegotiationStrategy) {
- iterator.set(new WebMvcAutoConfiguration.OptionalPathExtensionContentNegotiationStrategy(strategy));
- }
- }
-
- return manager;
- }
- }
-
- @Configuration
- @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
- @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})
- public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
- private static final Log logger = LogFactory.getLog(WebMvcConfigurerAdapter.class);
- private final ResourceProperties resourceProperties;
- private final WebMvcProperties mvcProperties;
- private final ListableBeanFactory beanFactory;
- private final HttpMessageConverters messageConverters;
- final WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
-
- public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, @Lazy HttpMessageConverters messageConverters, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
- this.resourceProperties = resourceProperties;
- this.mvcProperties = mvcProperties;
- this.beanFactory = beanFactory;
- this.messageConverters = messageConverters;
- this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
- }
-
- public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
- converters.addAll(this.messageConverters.getConverters());
- }
-
- public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
- Long timeout = this.mvcProperties.getAsync().getRequestTimeout();
- if (timeout != null) {
- configurer.setDefaultTimeout(timeout.longValue());
- }
-
- }
-
- public void configureContentNegotiation(ContentNegotiationConfigurer configurer) {
- Map<String, MediaType> mediaTypes = this.mvcProperties.getMediaTypes();
- Iterator var3 = mediaTypes.entrySet().iterator();
-
- while(var3.hasNext()) {
- Entry<String, MediaType> mediaType = (Entry)var3.next();
- configurer.mediaType((String)mediaType.getKey(), (MediaType)mediaType.getValue());
- }
-
- }
-
- @Bean
- @ConditionalOnMissingBean
- public InternalResourceViewResolver defaultViewResolver() {
- InternalResourceViewResolver resolver = new InternalResourceViewResolver();
- resolver.setPrefix(this.mvcProperties.getView().getPrefix());
- resolver.setSuffix(this.mvcProperties.getView().getSuffix());
- return resolver;
- }
-
- @Bean
- @ConditionalOnBean({View.class})
- @ConditionalOnMissingBean
- public BeanNameViewResolver beanNameViewResolver() {
- BeanNameViewResolver resolver = new BeanNameViewResolver();
- resolver.setOrder(2147483637);
- return resolver;
- }
-
- @Bean
- @ConditionalOnBean({ViewResolver.class})
- @ConditionalOnMissingBean(
- name = {"viewResolver"},
- value = {ContentNegotiatingViewResolver.class}
- )
- public ContentNegotiatingViewResolver viewResolver(BeanFactory beanFactory) {
- ContentNegotiatingViewResolver resolver = new ContentNegotiatingViewResolver();
- resolver.setContentNegotiationManager((ContentNegotiationManager)beanFactory.getBean(ContentNegotiationManager.class));
- resolver.setOrder(-2147483648);
- return resolver;
- }
-
- @Bean
- @ConditionalOnMissingBean
- @ConditionalOnProperty(
- prefix = "spring.mvc",
- name = {"locale"}
- )
- public LocaleResolver localeResolver() {
- if (this.mvcProperties.getLocaleResolver() == org.springframework.boot.autoconfigure.web.WebMvcProperties.LocaleResolver.FIXED) {
- return new FixedLocaleResolver(this.mvcProperties.getLocale());
- } else {
- AcceptHeaderLocaleResolver localeResolver = new AcceptHeaderLocaleResolver();
- localeResolver.setDefaultLocale(this.mvcProperties.getLocale());
- return localeResolver;
- }
- }
-
- @Bean
- @ConditionalOnProperty(
- prefix = "spring.mvc",
- name = {"date-format"}
- )
- public Formatter<Date> dateFormatter() {
- return new DateFormatter(this.mvcProperties.getDateFormat());
- }
-
- public MessageCodesResolver getMessageCodesResolver() {
- if (this.mvcProperties.getMessageCodesResolverFormat() != null) {
- DefaultMessageCodesResolver resolver = new DefaultMessageCodesResolver();
- resolver.setMessageCodeFormatter(this.mvcProperties.getMessageCodesResolverFormat());
- return resolver;
- } else {
- return null;
- }
- }
-
- public void addFormatters(FormatterRegistry registry) {
- Iterator var2 = this.getBeansOfType(Converter.class).iterator();
-
- while(var2.hasNext()) {
- Converter<?, ?> converter = (Converter)var2.next();
- registry.addConverter(converter);
- }
-
- var2 = this.getBeansOfType(GenericConverter.class).iterator();
-
- while(var2.hasNext()) {
- GenericConverter converter = (GenericConverter)var2.next();
- registry.addConverter(converter);
- }
-
- var2 = this.getBeansOfType(Formatter.class).iterator();
-
- while(var2.hasNext()) {
- Formatter<?> formatter = (Formatter)var2.next();
- registry.addFormatter(formatter);
- }
-
- }
-
- private <T> Collection<T> getBeansOfType(Class<T> type) {
- return this.beanFactory.getBeansOfType(type).values();
- }
-
- public void addResourceHandlers(ResourceHandlerRegistry registry) {
- if (!this.resourceProperties.isAddMappings()) {
- logger.debug("Default resource handling disabled");
- } else {
- Integer cachePeriod = this.resourceProperties.getCachePeriod();
- if (!registry.hasMappingForPattern("/webjars/**")) {
- this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{"/webjars/**"}).addResourceLocations(new String[]{"classpath:/META-INF/resources/webjars/"}).setCachePeriod(cachePeriod));
- }
-
- String staticPathPattern = this.mvcProperties.getStaticPathPattern();
- if (!registry.hasMappingForPattern(staticPathPattern)) {
- this.customizeResourceHandlerRegistration(registry.addResourceHandler(new String[]{staticPathPattern}).addResourceLocations(this.resourceProperties.getStaticLocations()).setCachePeriod(cachePeriod));
- }
-
- }
- }
-
- @Bean
- public WebMvcAutoConfiguration.WelcomePageHandlerMapping welcomePageHandlerMapping(ResourceProperties resourceProperties) {
- return new WebMvcAutoConfiguration.WelcomePageHandlerMapping(resourceProperties.getWelcomePage(), this.mvcProperties.getStaticPathPattern());
- }
-
- private void customizeResourceHandlerRegistration(ResourceHandlerRegistration registration) {
- if (this.resourceHandlerRegistrationCustomizer != null) {
- this.resourceHandlerRegistrationCustomizer.customize(registration);
- }
-
- }
-
- @Bean
- @ConditionalOnMissingBean({RequestContextListener.class, RequestContextFilter.class})
- public static RequestContextFilter requestContextFilter() {
- return new OrderedRequestContextFilter();
- }
-
- @Configuration
- @ConditionalOnProperty(
- value = {"spring.mvc.favicon.enabled"},
- matchIfMissing = true
- )
- public static class FaviconConfiguration {
- private final ResourceProperties resourceProperties;
-
- public FaviconConfiguration(ResourceProperties resourceProperties) {
- this.resourceProperties = resourceProperties;
- }
-
- @Bean
- public SimpleUrlHandlerMapping faviconHandlerMapping() {
- SimpleUrlHandlerMapping mapping = new SimpleUrlHandlerMapping();
- mapping.setOrder(-2147483647);
- mapping.setUrlMap(Collections.singletonMap("**/favicon.ico", this.faviconRequestHandler()));
- return mapping;
- }
-
- @Bean
- public ResourceHttpRequestHandler faviconRequestHandler() {
- ResourceHttpRequestHandler requestHandler = new ResourceHttpRequestHandler();
- requestHandler.setLocations(this.resourceProperties.getFaviconLocations());
- return requestHandler;
- }
- }
- }
- }
WebMvcProperties的源碼以下:
2,自動配置的靜態資源
在自動配置類的addResourceHandlers方法中定義瞭如下靜態資源的自動配置。
1)類路徑文件
把類路徑下的/static,/public,/resources和/META-INF/resources文件夾下的靜態文件直接映射爲/**,能夠經過http://localhost:8080/**來訪問。
2)webjar
何謂webjar,webjar就是將是咱們經常使用的腳本框架封裝在jar包中的jar包,更多關於webjar的內容請訪問http://www.webjars.org網站
把webjar的/META-INF/resources/webjars/下的靜態文件映射爲/webjar/**,能夠經過http://localhost:8080/webjar/**來訪問
3,自動配置的Formatter和Converter
關於自動配置的Formatter和Converter,咱們能夠看一下WebMvcAutoConfiguration類中的定義:
- public void addFormatters(FormatterRegistry registry) {
- Iterator var2 = this.getBeansOfType(Converter.class).iterator();
-
- while(var2.hasNext()) {
- Converter<?, ?> converter = (Converter)var2.next();
- registry.addConverter(converter);
- }
-
- var2 = this.getBeansOfType(GenericConverter.class).iterator();
-
- while(var2.hasNext()) {
- GenericConverter converter = (GenericConverter)var2.next();
- registry.addConverter(converter);
- }
-
- var2 = this.getBeansOfType(Formatter.class).iterator();
-
- while(var2.hasNext()) {
- Formatter<?> formatter = (Formatter)var2.next();
- registry.addFormatter(formatter);
- }
-
- }
從代碼中能夠看出,只要咱們定義了Converter,GenericConverter和Formatter接口的事項類的Bean,這些Bean就會自動註冊到Spring MVC中。
4,自動配置的HttpMessageConverters
在WebMvcAutoConfiguration中,咱們註冊了messageConverters,代碼以下:
- @Configuration
- @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
- @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})
- public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
- private static final Log logger = LogFactory.getLog(WebMvcConfigurerAdapter.class);
- private final ResourceProperties resourceProperties;
- private final WebMvcProperties mvcProperties;
- private final ListableBeanFactory beanFactory;
- private final HttpMessageConverters messageConverters;
- final WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer resourceHandlerRegistrationCustomizer;
-
- public WebMvcAutoConfigurationAdapter(ResourceProperties resourceProperties, WebMvcProperties mvcProperties, ListableBeanFactory beanFactory, @Lazy HttpMessageConverters messageConverters, ObjectProvider<WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer> resourceHandlerRegistrationCustomizerProvider) {
- this.resourceProperties = resourceProperties;
- this.mvcProperties = mvcProperties;
- this.beanFactory = beanFactory;
- this.messageConverters = messageConverters;
- this.resourceHandlerRegistrationCustomizer = (WebMvcAutoConfiguration.ResourceHandlerRegistrationCustomizer)resourceHandlerRegistrationCustomizerProvider.getIfAvailable();
- }
-
- public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
- converters.addAll(this.messageConverters.getConverters());
- }
-
- public void configureAsyncSupport(AsyncSupportConfigurer configurer) {
- Long timeout = this.mvcProperties.getAsync().getRequestTimeout();
- if (timeout != null) {
- configurer.setDefaultTimeout(timeout.longValue());
- }
-
- }
在這裏直接注入了HttpMessageConverters的Bean,而這個Bean是在HttpMessageConvertersAutoConfiguration類中定義的,咱們自動掃描註冊的HttpMessage Converter除了Spring MVC默認的ByteArrayHttpMessageConverter,StringHttpMessage Converter,Resource HttpMessageConverter等外,還自動配置文件裏引入了JacksonHttpMessageConverters Configuration和GsonHttpMessage ConverterConfiguration,使咱們得到了額外的HttpMessageConverter:
若jackson的jar包在路徑上,則Spring Boot經過JacksonHttpMessage Converters Configuration增長了MappingJackson2HttpMessage Converter和Mapping Jackson2XmlHttpMessageConverter
若gson的jar包在路徑上,則Spring Boot經過GsonHttpMessageConverterConfiguration增長GsonHttpMessageConverter
在Spring Boot中若是要新增自定義的HttpMessageConverter,則只需定義一個你本身的HttpMessageConverters的Bean,而後在此Bean中註冊自定義的HttpMessageConverter便可,以下:
- @Bean
- public HttpMessageConverters customConverters(){
- HttpMessageConverter<?> customConverter1 = new CustomConverter1();
- HttpMessageConverter<?> customConverter2 = new CustomConverter2();
- return new HttpMessageConverters(customConverter1,customConverter2)
- }
5,靜態首頁的支持
把靜態index.html文件放置在以下目錄
classpath:/META-INF/resources/index.html
classpath:/resources/index.html
classpath:/static/index.html
classpath:/public/index.html
當咱們訪問應用根目錄http://localhost:8080/時,會直接映射
二:接管Spring Boot的Web配置
若是Spring Boot提供的Spring MVC默認配置不符合需求,則能夠經過一個配置類(註解有@Configuration的類)加上@EnableWebMvc註解來實現徹底本身控制的MVC配置。
一般狀況下,Spring Boot的自動配置是符合咱們大多數需求的。在你既須要保留Spring Boot提供的便利,又須要增長本身額外的配置的時候,能夠定義一個配置類並繼承WebMvcConfigurerAdapter,無須使用@EnableWebMvc,例如:
上注意,上面重寫了了addViewController方法,並不會覆蓋WebMvcAutoConfiguration中的addViewController(在此方法中Spring Boot將「/」映射至index.html),這也就意味着咱們本身的配置和Spring Boot的自動配置同時有效,這也是推薦添加本身的MVC配置的方式。
三:接註冊Servlet,Filter,Listener
當使用嵌入式的Servlet容器時,咱們經過將Servlet,Filter和Listener聲明爲Spring Bean而達到註冊的效果;或者註冊ServletRegistrationBean,FilterRegistrationBean和ServletListenerRegistrationBean的Bean。
1)直接註冊Bean示例,代碼以下:
- @Bean
- public XxServlet xxServlet(){
- return new XxServlet();
- }
-
- @Bean
- public YyFilter yyFilter(){
- return new YyFilter();
- }
-
- @Bean
- public ZzListener zzListener(){
- return new ZzListener()
- }
2)經過RegistrationBean
- @Bean
- public ServeletRegistrationBean serveletRegistrationBean(){
- return new ServeletRegistrationBean(new Xxservlet(),"/xx/*");
- }
-
- @Bean
- public FilterRegistrationBean filterRegistrationBean(){
- FilterRegistrationBean registrationBean = new FilterRegistrationBean();
- registrationBean.setFilter(new YyFilter());
- registrationBean.setOrder(2);
- return registrationBean;
- }
- @Bean
- public ServletListenerRegistrationBean<ZzListener> zzListenerServletListenerRegistrationBean(){
- return new ServletListenerRegistrationBean<ZzListener>(new ZzListener())