Spring MVC自动配置

Spring MVC自动配置


Spring Boot为Spring MVC提供了自动配置,适用于大多数应用程序。

自动配置在Spring的默认值之上添加了以下功能:
包含ContentNegotiatingViewResolver和BeanNameViewResolver beans。
ContentNegotiatingViewResolver:组合所有视图解析器

支持提供静态资源,包括对WebJars的支持( 本文档稍后介绍))。

自动注册Converter,GenericConverter和Formatter
Converter:转换器
Formatter :格式化器 将页面带来的日期2017-12-12 ===》转到后台为Date
beans。

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

        }

支持HttpMessageConverters:响应转换器 User ===》json
HttpMessageConverters
Spring MVC使用HttpMessageConverter接口转换HTTP请求和响应。明智的默认设置包含在开箱即用中。例如,对象可以自动转换为JSON(通过使用Jackson库)或XML(如果可用,使用Jackson XML扩展,或者如果Jackson XML扩展不是,则使用JAXB可用)。默认情况下,字符串以UTF-8编码。

如果您需要添加或自定义转换器,可以使用Spring Boot的HttpMessageConverters类,如下面的清单所示:

import org.springframework.boot.autoconfigure.web.HttpMessageConverters;
import org.springframework.context.annotation.*;
import org.springframework.http.converter.*;

@Configuration
public class MyConfiguration {

	@Bean
	public HttpMessageConverters customConverters() {
		HttpMessageConverter<?> additional = ...
		HttpMessageConverter<?> another = ...
		return new HttpMessageConverters(additional, another);
	}

}

上下文中存在的任何HttpMessageConverter bean都将添加到转换器列表中。您也可以以相同的方式覆盖默认转换器。


自动注册MessageCodesResolver( 本文档后面部分)。
MessageCodesResolver
Spring MVC有一个生成错误代码的策略,用于从绑定错误中呈现错误消息:MessageCodesResolver。如果设置spring.mvc.message-codes-resolver.format属性PREFIX_ERROR_CODE或POSTFIX_ERROR_CODE,则Spring Boot会为您创建一个(请参阅枚举 DefaultMessageCodesResolver.Format


静态index.html支持。
自定义Favicon支持(本文档稍后介绍)
自动使用ConfigurableWebBindingInitializer bean(本文 后面会介绍)。
静态内容
默认情况下,Spring Boot从类路径中的/static(或/public或/resources或/META-INF/resources)目录或ServletContext的根目录中提供静态内容。它使用来自Spring MVC的ResourceHttpRequestHandler,以便您可以通过添加自己的WebMvcConfigurer并覆盖addResourceHandlers方法来修改该行为
默认情况下,资源映射到/**    
但您可以使用    spring.mvc.static-path-pattern    属性对其进行调整。例如,将所有资源重新定位到/resources/**
可以实现如下:
spring.mvc.static-path-pattern=/resources/**
您还可以使用spring.resources.static-locations属性自定义静态资源位置(将默认值替换为目录位置列表)。根Servlet上下文路径"/"也会自动添加为位置。

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

ContentNegotiatingViewResolver 内容如下

  protected void initServletContext(ServletContext servletContext) {
        Collection<ViewResolver> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(this.obtainApplicationContext(), ViewResolver.class).values();
        ViewResolver viewResolver;
        if (this.viewResolvers == null) {
            this.viewResolvers = new ArrayList(matchingBeans.size());
            Iterator var3 = matchingBeans.iterator();

            while(var3.hasNext()) {
                viewResolver = (ViewResolver)var3.next();
                if (this != viewResolver) {
                    this.viewResolvers.add(viewResolver);
                }
            }
        } else {
            for(int i = 0; i < this.viewResolvers.size(); ++i) {
                viewResolver = (ViewResolver)this.viewResolvers.get(i);
                if (!matchingBeans.contains(viewResolver)) {
                    String name = viewResolver.getClass().getName() + i;
                    this.obtainApplicationContext().getAutowireCapableBeanFactory().initializeBean(viewResolver, name);
                }
            }
        }

如果你想保留Spring Boot MVC功能,并且你想添加额外的 MVC配置(拦截器,格式化程序,视图控制器和其他功能),你可以添加自己的
@Configuration类WebMvcConfigurer类但不能标注@EnableWebMvc。如果您希望提供RequestMappingHandlerMapping,RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver的自定义实例,则可以声明WebMvcRegistrationsAdapter实例以提供此类组件。

//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能 
@Configuration 
public class MyMvcConfig extends WebMvcConfigurerAdapter { 
	@Override public void addViewControllers(ViewControllerRegistry registry) { 
	 //浏览器发送 /atguigu 请求来到 success 
	 registry.addViewController("/atguigu").setViewName("success"); 
	}
}


原理:


    @Configuration
    @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
    @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})
    @Order(0)
    public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer {



@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
EnableWebMvcConfiguration.class 内容如下
@Configuration
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware 		 {
     private final ResourceProperties resourceProperties;
     private final WebMvcProperties mvcProperties;
     private final ListableBeanFactory beanFactory;
     private final WebMvcRegistrations mvcRegistrations;
     private ResourceLoader resourceLoader;
     }

DelegatingWebMvcConfiguration 内容如下

@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
    private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

    public DelegatingWebMvcConfiguration() {
    }

从容器中获取所有的WebMvcConfigur
    @Autowired(
        required = false
    )
    public void setConfigurers(List<WebMvcConfigurer> configurers) {
        if (!CollectionUtils.isEmpty(configurers)) {
            this.configurers.addWebMvcConfigurers(configurers);
        }

    }


 protected void addViewControllers(ViewControllerRegistry registry) {
        this.configurers.addViewControllers(registry);
    }
}

addViewControllers(registry); 参考实现

 public void addViewControllers(ViewControllerRegistry registry) {
        Iterator var2 = this.delegates.iterator();
			拿到所有的 WebMvcConfigurer 
        while(var2.hasNext()) {
            WebMvcConfigurer delegate = (WebMvcConfigurer)var2.next();
            delegate.addViewControllers(registry);
        }

    }

如果您想完全控制Spring MVC,可以添加自己的@Configuration注释@EnableWebMvc。所有的内容都是自己配置


为啥一配置@EnableWebMvc springmvc的自动配置就会失效呢?

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}

DelegatingWebMvcConfiguration.class

@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
    private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();

webmvc 没有这个组件 WebMvcConfigurationSupport.class,下面的配置文件才会生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})

DelegatingWebMvcConfiguration.class 这个却恰恰继承了 WebMvcConfigurationSupport,如果配置@EnableWebMvc这个注解,自动配置就会失效

@Configuration
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
webmvc 没有这个组件 WebMvcConfigurationSupport.class,下面的配置文件才会生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})

@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值