SpringMVC自动配置原理
Spring Boot 为 Spring MVC 提供了自动配置,适用于大多数应用程序。
自动配置在 Spring 的默认值之上添加了以下功能:
包括ContentNegotiatingViewResolver
(视图解析器:根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发?重定向?))和BeanNameViewResolver
。
ContentNegotiatingViewResolver
:组合所有的视图解析器。
如何定制:我们可以给自己的容器中添加一个视图解析器。自动的将其组合进来;
@Bean
public ViewResolver myViewResolver(){
return new MyViewResolver();
}
private static class MyViewResolver implements ViewResolver{
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
return null;
}
}
支持提供静态资源,包括对 WebJars 的支持。
自动注册Converter
,GenericConverter
和Formatter
类。
Converter
:转换器;public String hello(User user);类型转换使用
Formatter
:格式化器;2020-07-07 ==== >Date;
@Bean
public FormattingConversionService mvcConversionService() {
Format format = this.mvcProperties.getFormat();
//在文件中配置日期格式化器的规则
WebConversionService conversionService = new WebConversionService((new DateTimeFormatters()).dateFormat(format.getDate()).timeFormat(format.getTime()).dateTimeFormat(format.getDateTime()));
//添加日期格式化组件 this.addFormatters(conversionService);
return conversionService;
}
自己添加的格式化转换器,我们只需要放在容器中即可
支持HttpMessageConverters
。
HttpMessageConverters
:SpringMvc用来转换Http请求和响应的;User转换为Json格式。
HttpMessageConverters
是从容器中确定;获取所有HttpMessageConverters
;自己给容器中添加HttpMessageConverters
只需要将自己的组件注册在容器中(@Bean,@Component)
@Configuration(proxyBeanMethods = false)
public class MyHttpMessageConvertersConfiguration {
@Bean
public HttpMessageConverters customConverters() {
HttpMessageConverter<?> additional = new AdditionalHttpMessageConverter();
HttpMessageConverter<?> another = new AnotherHttpMessageConverter();
return new HttpMessageConverters(additional, another);
}
}
自动注册MessageCodesResolver
。定义错误代码生成规则
静态index.html支持。
ConfigurableWebBindingInitializerbean
的自动使用。
2、扩展SpringMvc
<mvc:view-controller path="/hello" view-name="success"></mvc:view-controller>
<mvc:interceptors>
<mvc:interceptor>
<mvc:mapping path="/hello"/>
<bean></bean>
</mvc:interceptor>
</mvc:interceptors>
如果您想保留那些Spring Boot MVC
自定义并进行更多MVC 自定义(拦截器、格式化程序、视图控制器和其他功能),您可以添加自己@Configuration
的类型类,WebMvcConfigurer
但不添加 @EnableWebMvc
。
如果你想提供的定制情况RequestMappingHandlerMapping
,RequestMappingHandlerAdapter
或者ExceptionHandlerExceptionResolver
,仍然保持弹簧引导MVC自定义,你可以声明类型的WebMvcRegistrations
,并用它来提供这些组件的定制实例。
如果你想利用Spring MVC中的完全控制,你可以添加自己的@Configuration
注解为@EnableWebMvc
,或者添加自己的@Configuration-annotatedDelegatingWebMvcConfiguration
中的Javadoc中所述@EnableWebMvc
。
**编写一个配置类 用@Configuration
;不能标注 @EnableWebMvc.**
在spring boot 2.0以后 WebMvcConfigurerAdapter
这个方法已经过时,通过百度网上的资料之后发现很多人说是改成继承WebMvcConfigurationSupport
这个类,这种方式是有问题的,会导致自动配置失效,应该是实现WebMvcConfigurer这个接口。
即保留了所有自动配置,也能用我们扩展的配置。
//以前使用WebMvcConfigurerAdapte可以来扩展SpringMvc的功能;现在使用的是WebMvcConfigurer
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// WebMvcConfigurer.super.addViewControllers(registry);
//发送什么页面去什么请求;浏览器发送test请求来到success页面
registry.addViewController("/testView").setViewName("test");
}
}
原理:
1、WebMvcAutoConfiguratuion是SpringMvc 的自动配置类。
2、
@Configuration(
proxyBeanMethods = false
)
@EnableConfigurationProperties({WebProperties.class})
public static class EnableWebMvcConfiguration extends DelegatingWebMvcConfiguration implements ResourceLoaderAware {
//从容器中获取所有的WebMvcConfigurer
@Autowired(
required = false
)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
//一个参考实现,将所有的WebMvcConfigurer相关配置都来一起调用。
// public void addViewControllers(ViewControllerRegistry registry) {
// Iterator var2 = this.delegates.iterator();
// while(var2.hasNext()) {
// WebMvcConfigurer delegate = (WebMvcConfigurer)var2.next();
// delegate.addViewControllers(registry);
}
}
}
}
3、所有的容器中WebMvcConfigurer都会一起来起作用。
4、我们的配置类也会被调用。
效果:SpringMvc的自动配置和我们的扩展配置都会起作用。
3、全面接管SpringMvc
Springboot对SpringMvc的的自动配置我们都不要了,所有的都是我们自己自己配。所有的Web模块,自动配置都失效。
我们需要在配置类中只需要添加@EnableWebMvc即可。
@Configuration
//全面接管,不推荐
@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer {
原理:为什么加了@EnableWebMvc,自动配置就失效了?
1、EnableWebMvc的核心
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}
2、
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
3、
@Configuration(
proxyBeanMethods = false
)
@ConditionalOnWebApplication(
type = Type.SERVLET
)
@ConditionalOnClass({Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class})
//判断容器中没有这个组件的时候,自动配置类才生效
@ConditionalOnMissingBean({WebMvcConfigurationSupport.class})
@AutoConfigureOrder(-2147483638)
@AutoConfigureAfter({DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class, ValidationAutoConfiguration.class})
4、@EnableWebMvc将DelegatingWebMvcConfiguration导入进来了。
5、导入的DelegatingWebMvcConfiguration只是SpringMvc最基本的功能。
5、如何修改SpringBoot 的默认配置
模式:
1、SpringBoot 在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有,就用用户配置的,如果没有才自动配置。如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认配置的组合起来。
2、在SpringBoot中会有非常多的xxConfigurer帮助我们进行扩展配置。