springboot自动配置webMvcAutoConfiguration和自定制springmvc

1、思想

在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:

  1. Inclusion of ContentNegotiatingViewResolver and BeanNameViewResolver beans.
  2. Support for serving static resources, including support for WebJars (see below).
  3. Automatic registration of Converter, GenericConverter, Formatter beans.
  4. Support for HttpMessageConverters (see below).
  5. Automatic registration of MessageCodesResolver (see below).
  6. Static index.html support.
  7. Custom Favicon support (see below).
  8. Automatic use of a ConfigurableWebBindingInitializer bean (see below).

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.

2、 分析第三,四,五点,自动注册了convert和formatter

在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)。

3、EnableWebMvcConfiguration

在上面的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.

4、@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一样都需要自己配置

4、总结

如果我们想自定义配置的话可以建一个对象的类,加入到容器
​ 1)、SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;

​ 2)、在SpringBoot中会有非常多的xxxConfigurer帮助我们进行扩展配置(wenMvcConfigurer)

​ 3)、在SpringBoot中会有很多的xxxCustomizer帮助我们进行定制配置。

发布了16 篇原创文章 · 获赞 0 · 访问量 416

猜你喜欢

转载自blog.csdn.net/weixin_43532415/article/details/104974449
今日推荐