扩展MVC
SpringBoot在自动配置很多组件的时候,先看容器中有没有用户自己配置的(如果用户自己配置@bean),如果有就用用户配置的,如果没有就用自动配置的;
如果有些组件可以存在多个,比如我们的视图解析器,就将用户配置的和自己默认的组合起来!
扩展使用SpringMVC:
如果想保留 Spring Boot MVC的特性,而且还想扩展新的功能(拦截器, 格式化器, 视图控制器等),你可以
在你自定义的 WebMvcConfigurer 类上增加 @Configuration 注解。
自定义配置类保留了所有的自动配置, 也能用我们扩展的功能
//应为类型要求为WebMvcConfigurer,所以我们实现其接口
//可以使用自定义类扩展MVC的功能
@Configuration
public class MyMvcConfig implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry) {
// 浏览器发送/test , 就会跳转到test页面;
registry.addViewController("/test").setViewName("test");
}
}
我们去浏览器访问一下:
确实也跳转过来了!所以说,我们要扩展SpringMVC,官方就推荐我们这么去使用,既保SpringBoot留所有的自动配置,也能用我们扩展的配置!
原理:
- 自定义WebMvcConfigurer自动配置时会导入;
WebMvcAutoConfiguration是 SpringMVC的自动配置类,里面有一个类WebMvcAutoConfigurationAdapter
这个类上有一个注解,在做其他自动配置时会导入:@Import(EnableWebMvcConfiguration.class)
- @Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})
导入EnableWebMvcConfiguration.class
@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class}) @EnableConfigurationProperties({WebMvcProperties.class, ResourceProperties.class})
@Order(0)
public static class WebMvcAutoConfigurationAdapter implements WebMvcConfigurer, ResourceLoaderAware {
- 我们点进EnableWebMvcConfiguration这个类看一下,EnableWebMvcConfiguration 继承了
DelegatingWebMvcConfiguration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
// 从容器中获取所有的webmvcConfigurer
@Autowired(required = false)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if (!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
}
分析 DelegatingWebMvcConfiguration , 会将所有web配置组件加到WebMvcConfigurerComposite中,
保留原来的配置类,也添加了新的配置类,所有的WebMvcConfigurer都会一起起作用
效果:SpringMVC的自动配置和我们的扩展配置都会起作用;
全面控制 SpringMVC
全面接管即:SpringBoot对SpringMVC的自动配置不需要了,所有都是我们自己去配置!
只需在我们的配置类中要加一个@EnableWebMvc。
我们看下如果我们全面接管了SpringMVC了,我们之前SpringBoot给我们配置的静态资源映射一定会无效,我们可以去测试一下;
给配置类加上注解:@EnableWebMvc
我们发现所有的SpringMVC自动配置都失效了!回归到了最初的样子;
当然,我们开发中,不推荐使用全面接管SpringMVC
思考问题?为什么加了一个注解,自动配置就失效了!我们看下源码:
- 1、这里发现它是导入了一个类,我们可以继续进去看
@Import({DelegatingWebMvcConfiguration.class})
public @interface EnableWebMvc {
}
2、它继承了一个父类 WebMvcConfigurationSupport
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
// ......
}
3、我们来回顾一下Webmvc自动配置类
@Configuration(proxyBeanMethods = false)
@ConditionalOnWebApplication(type = Type.SERVLET)
@ConditionalOnClass({ Servlet.class, DispatcherServlet.class, WebMvcConfigurer.class })
// 这个注解的意思就是:容器中没有这个组件的时候,这个自动配置类才生效
@ConditionalOnMissingBean(WebMvcConfigurationSupport.class)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE + 10)
@AutoConfigureAfter({ DispatcherServletAutoConfiguration.class, TaskExecutionAutoConfiguration.class,
ValidationAutoConfiguration.class })
public class WebMvcAutoConfiguration {
}
总结一句话:@EnableWebMvc将WebMvcConfigurationSupport组件导入进来了;
而导入的WebMvcConfigurationSupport只是SpringMVC最基本的功能!
总结 SpringMVC 配置
- 在Spring Boot中自已配置组件的时候,先看容器中有没有公司自已配置的(
@Bean、@Component),如果
有就用公司自已配置的; 如果没有,才自动配置. - 在Spring Boot中会有非常多的
xxxConfigurer帮助我们进行扩展配置. - 在Spring Boot中会有很多的
xxxCustomizer帮助我们进行定制配置.