目录
一、自动配置原理
Spring Boot为Spring MVC提供了自动配置,可与大多数应用程序完美配合。
以下是Spring Boot对Spring MVC的默认配置
org.springframework.boot.autoconfigurae.web.servlet.WebMvcAutoConfiguration
自动配置在Spring的默认值之上添加了以下功能:
- 包含
ContentNegotiatingViewResolver
和BeanNameViewResolver
。 ---->视图解析器 - 支持服务静态资源,包括对WebJars的支持(官方文档中有介绍
)。 —>静态资源文件夹路径 - 自动注册
Converter
、GenericConverter
和Formatter
Beans。 —>转换器,格式化器 - 支持
HttpMessageConverters
(官方文档中有介绍
)。 —>SpringMVC用来转换Http请求和响应的;User —Json; - 自动注册
MessageCodesResolver
(官方文档中有介绍
)。 —>定义错误代码生成规则 - 静态
index.html
支持。 —>静态首页访问 - 定制
favicon
支持(官方文档中有介绍
)。 —>网站图标 - 自动使用
ConfigurableWebBingdingInitializer
bean(官方文档中有介绍
)。
如果您想保留Spring Boot MVC的功能,并且需要添加其他MVC配置(拦截器,格式化程序和视图控制器等),可以添加自己的WebConfigurer
类型的@Configuration
类,但不能带@EnableWebMvc
注解。如果您想自定义RequestMappingHandlerMapping
、RequestMappingHandlerAdapter
或者ExceptionHandlerExceptionResolver
实例,可以声明一个WebMvcRegistrationsAdapter
实例来提供这些组件。
如果您想完全掌控Spring MVC,可以添加自定义注解@EnableWebMvc
的@Configuration
配置类。
二、视图解析器
根据方法的返回值得到视图对象(View),视图对象决定如何渲染(转发or重定向)
- 自动配置了ViewResolver
- ContentNegotiatingViewResolver:组合所有的视图解析器的;
视图解析器从哪来的?
所以我们可以自己给容器中添加一个视图解析器;自动的将其组合进来
@Component
public class MyViewResolver implements ViewResolver {
@Override
public View resolveViewName(String s, Locale locale) throws Exception {
return null;
}
}
三、转换器、格式化器
-Converter:转换器;public String hello(User user):类型转换使用
Converter(表单数据转为user)
- Formatter 格式化器; 2020.12.12===Date;
@Bean
//在配置文件中配置日期格式化的规则
@ConditionalOnProperty(prefix = "spring.mvc", name = "date-format")
public Formatter<Date> dateFormatter() {
return new DateFormatter(this.mvcProperties.getDateFormat());//日期格式化组件
}
自己添加的格式化器转换器,我们只需要放在容器中即可
四、HttpMessageConverters
HttpMessageConverter
:SpringMVC用来转换Http请求和响应的;User —Json;HttpMessageConverters
:是从容器中确定;获取所有的HttpMessageConverter;
自己给容器中添加HttpMessageConverter,只需要将自己的组件注册容器中(@Bean,@Component)
五、MessageCodesResolver
我们可以配置一个ConfigurableWebBindingInitializer来替换默认的;(添加到容器)
六、扩展SpringMVC
以前的配置文件中的配置
<mvc:view-controller path="/hello" view-name="success"/>
现在,编写一个配置类(@Configuration),是WebMvcConfigurer类型;不能标注@EnableWebMvc
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/hi").setViewName("success");
}
}
访问:http://localhost:8080/hi
原理:
我们知道WebMVCAutoConfiguration
是SpringMVC的自动配置类
下面这个类是WebMVCAutoConfiguration
中的一个内部类
看一下@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
中的这个类,
这个类依旧是WebMvcAutoConfiguration
中的一个内部类
重点看一下这个类继承的父类DelegatingWebMvcConfiguration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
public DelegatingWebMvcConfiguration() {
}
//自动注入,从容器中获取所有的WebMvcConfigurer
@Autowired(
required = false
)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
......
/**
* 查看其中一个方法
* this.configurers:也是WebMvcConfigurer接口的一个实现类
* 看一下调用的configureViewResolvers方法 ↓
*/
protected void configureViewResolvers(ViewResolverRegistry registry) {
this.configurers.configureViewResolvers(registry);
}
public void configureViewResolvers(ViewResolverRegistry registry) {
Iterator var2 = this.delegates.iterator();
while(var2.hasNext()) {
WebMvcConfigurer delegate = (WebMvcConfigurer)var2.next();
//将所有的WebMvcConfigurer相关配置都来一起调用;
delegate.configureViewResolvers(registry);
}
}
容器中所有的WebMvcConfigurer都会一起起作用;
我们的配置类也会被调用;
效果:SpringMVC的自动配置和我们的扩展配置都会起作用;
七、全面接管SpringMVC
SpringBoot对SpringMVC的自动配置不需要了,所有都是由我们自己来配置;所有的SpringMVC的自动配置都失效了。
我们只需要在配置类中添加@EnableWebMvc即可
@Configuration
@EnableWebMvc
public class MyMvcConfig implements WebMvcConfigurer
原理:
为什么@EnableWebMvc自动配置就失效了;
我们看一下EnableWebMvc注解类
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
@Documented
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}
重点在于@Import({DelegatingWebMvcConfiguration.class})
DelegatingWebMvcConfiguration
是WebMvcConfigurationSupport
的子类
我们再来看一下SpringMVC的自动配置类WebMvcAutoConfiguration
@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})
public class WebMvcAutoConfiguration
- @EnableWebMvc将WebMvcConfigurationSupport组件导入进来;
- 导入的WebMvcConfigurationSupport只是SpirngMVC最基本的功能;
八、如何修改Spring Boot的默认配置
SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(@Bean、@Component)如果有就用用户配置的,如果没有,才自动配置;如果有些组件可以有多个(ViewResolver)将用户配置的和自己默认的组合起来;