在springboot文档里有关于springmvc自动配置的一段话
Spring MVC auto-configuration
Spring Boot provides auto-configuration for Spring MVC that works well with most applications.
The auto-configuration adds the following features on top of Spring’s defaults:
If you want to keep Spring Boot MVC features, and you just want to add additional MVC configuration (interceptors, formatters, view controllers etc.) you can add your own @Configuration class of type WebMvcConfigurerAdapter, but without @EnableWebMvc. If you wish to provide custom instances of RequestMappingHandlerMapping, RequestMappingHandlerAdapter or ExceptionHandlerExceptionResolver you can declare a WebMvcRegistrationsAdapter instance providing such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration annotated with @EnableWebMvc.
在webMvcAutoConfiguration类中有WebMvcAutoConfigurationAdapter静态内部类,继承了WebMvcConfigurerAdapter(抽象类实现了WebMvcConfigurer接口),WebMvcConfigurer里有各种配置方法,比如说void addFormatters(FormatterRegistry registry);void addInterceptors(InterceptorRegistry registry);对应的源码如下
@Configuration
@Import(EnableWebMvcConfiguration.class)
@EnableConfigurationProperties({ WebMvcProperties.class, ResourceProperties.class })
public static class WebMvcAutoConfigurationAdapter extends WebMvcConfigurerAdapter {
........................
public Formatter<Date> dateFormatter() {
return new DateFormatter(this.mvcProperties.getDateFormat());
}
@Override
public MessageCodesResolver getMessageCodesResolver() {
if (this.mvcProperties.getMessageCodesResolverFormat() != null) {
DefaultMessageCodesResolver resolver = new DefaultMessageCodesResolver();
resolver.setMessageCodeFormatter(
this.mvcProperties.getMessageCodesResolverFormat());
return resolver;
}
return null;
}
@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);
}
}
@Override
public MessageCodesResolver getMessageCodesResolver() {
if (this.mvcProperties.getMessageCodesResolverFormat() != null) {
DefaultMessageCodesResolver resolver = new DefaultMessageCodesResolver();
resolver.setMessageCodeFormatter(
this.mvcProperties.getMessageCodesResolverFormat());
return resolver;
}
return null;
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.addAll(this.messageConverters.getConverters());
}
.......
}
第三点,可以看到addformatter里有getBeansOfType,会从容器里取出所有的Converter,Formatter,GenericConverter。自己添加的格式化器转换器,我们只需要放在容器中即可
第五点,会从配置properties里面得到MessageCodesResolverFormat,就可以自动完成它的注册。
第四点,HttpMessageConverter:SpringMVC用来转换Http请求和响应的;User—Json;
HttpMessageConverters
是从容器中确定;获取所有的HttpMessageConverter;
自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中(@Bean,@Component)。
在上面的adapter上面import的EnableWebConfiguration,源码如下
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration {
..............
@Override
protected ConfigurableWebBindingInitializer getConfigurableWebBindingInitializer() {
try {
return this.beanFactory.getBean(ConfigurableWebBindingInitializer.class);
}
catch (NoSuchBeanDefinitionException ex) {
return super.getConfigurableWebBindingInitializer();
}
}
}
可以发现会从容器中得到Initializer,我们可以配置一个ConfigurableWebBindingInitializer来替换默认的;(添加到容器)初始化WebDataBinder;请求数据=====JavaBean;
继承的DelegatingWebMvcConfiguratio源码:
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
}
@Autowired(required = false)作用与set函数上,参数自动从容器里寻找,因此此类会将所有webMvcConfigurer(自己配置的与自动配置的)配置好。
那么如果我们想要自定义配置的话,只需要建一个类实现webMvcConfigurer,然后添加到容器。示例如下
//使用WebMvcConfigurerAdapter可以来扩展SpringMVC的功能
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// super.addViewControllers(registry);
//浏览器发送 /atguigu 请求来到 success
registry.addViewController("/atguigu").setViewName("success");
}
}
注意不要在上面注解@EnableWebMvc.
源码:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
@Import(DelegatingWebMvcConfiguration.class),组件源码:
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
...........
}
继承的类WebMvcConfigurationSupport,而webMvcAutoConfiguration类
@Configuration
@ConditionalOnWebApplication
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class,
WebMvcConfigurerAdapter.class })
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
.............
}
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)所以自动装配不会生效。因此加了
@EnableWebMvc意味着自动配置失效,就像做springmvc一样都需要自己配置
如果我们想自定义配置的话可以建一个对象的类,加入到容器
1)、SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;
2)、在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置(wenMvcConfigurer)
3)、在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置。