组件扩展使用方法和说明部分
If you want to keep Spring Boot MVC features and you want to add additional MVC configuration (interceptors, formatters, view controllers, and other features), you can add your own @Configuration
class of type WebMvcConfigurer
but without @EnableWebMvc
. If you wish to provide custom instances of RequestMappingHandlerMapping
, RequestMappingHandlerAdapter
, or ExceptionHandlerExceptionResolver
, you can declare a WebMvcRegistrationsAdapter
instance to provide such components.
If you want to take complete control of Spring MVC, you can add your own @Configuration
annotzaated with @EnableWebMvc
.
在SpringBoot的指导目录可以看通过点击The “Spring Web MVC Framework”索引进入找到
意思是你想要在保留原来SpringBoot自动配置的MVC功能的前提下添加一些组件的话,你需要建一个配置类,这个配置类@Configuration的类型为WebMvcConfigurer。
这里注意:
在SpringBoot中WebMvcConfigurerAdapter这个类已经过时,spirng官网推荐用实现WebMvcConfigurer这个接口来添加组件,这个接口的方法都是普通方法,无需实现所有方法。
WebMvcConfigurer这个接口里面的空方法对应的是SpringMVC的一些扩展功能组件,如果需要就在自定义的配置类里重写着些方法返回你自己的组件就可以了。
(
如下
例子
)
@Configuration
public class MyMvcConfig extends WebMvcConfigurerAdapter {
//浏览器发送请求到
@Override
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/fanren01").setViewName("success");
}
//所有的WebMvcConfigurerAdapter组件都会一起作用
@Bean
public WebMvcConfigurerAdapter webMvcConfigurerAdapter(){
WebMvcConfigurerAdapter Adapter = new WebMvcConfigurerAdapter() {
@Override
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/").setViewName("login");
registry.addViewController("/index.html").setViewName("login");
registry.addViewController("/index").setViewName("login");
registry.addViewController("/main.html").setViewName("dashboard");
}
//注册拦截器
@Override
public void addInterceptors(InterceptorRegistry registry){
//拦截任意多层路径下的任意请求,排除(登陆页面,登陆请求,静态资源,bootstrap`jquery)
//springboot已经处理好了静态资源映射,不需要我们来处理
registry.addInterceptor(new LoginHandlerInterceptor()).addPathPatterns("/**")
.excludePathPatterns("/index.html","/","/index","/user/login",
"/asserts/**","/webjars/**");
}
};
return Adapter;
}
其实意思就是@Configuration会把自定义的配置类添加到spring容器中,而容器中发现你这个配置类继承或实现了指定的方法,SpringBoot就知道这个配置类是哪一个子框架的了。然后配置类里面的@Bean方法会把某些你要用的组件放入到容器中然后子框架启动的时候也会扫描到这些组件然后就能扩展这个功能了(其实这一步本来是需要配置文件中添加的)
实际操作:自定义配置类实现WebMvcConfigurer接口然后往容器里面(添加你的组件或从写方法)
这里我还是不太明白扩展功能是靠的添加组件还是说重写方法,下面的部分是重写方法的。按道理来书来说应该是扩展靠重写,更换自定义组件靠添加。这里存疑
添加组件的原理:源代码分析部分
一、如打开WebMvcAutoConfiguration这个自动配置类,你就可以发现,它里面也是实现WebMvcConfigurer这个接口然后重写方法而已。
注意@Override这个注解只是重写时用来辅助检查方法定义是否正确在源码中不一定看到的
二、重写了WebMvcConfigurer的配置类凭借@Configuration加入到容器
三、
1.然后WebMvcAutoConfiguration类里面有一个WebMvcAutoConfigurationAdapter类里面的注解@Import({WebMvcAutoConfiguration.EnableWebMvcConfiguration.class})这里相当与以前的配置文件引入自定义配置文件
2.EnableWebMvcConfiguration.class继承了DelegatingWebMvcConfiguration这个接口
3.DelegatingWebMvcConfiguration这个接口里面的方法就是从容器中获取所有的WebMvcConfigurer(包括自动的和自定义的),然后把它们(所有的WebMvcConfigurer)的某个方法都调用一次。
源代码很高大上的样子,其实里面的实现的思想都是简单至极,就代码多起来就看着麻烦不容易理解。如下
从容器中获取所有的WebMvcConfigurer,下面为一部分代码
@Configuration
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
private final WebMvcConfigurerComposite configurers = new WebMvcConfigurerComposite();
public DelegatingWebMvcConfiguration() {
}
//从容器中获取所有的configurer
@Autowired(
required = false
)
public void setConfigurers(List<WebMvcConfigurer> configurers) {
if(!CollectionUtils.isEmpty(configurers)) {
this.configurers.addWebMvcConfigurers(configurers);
}
}
//点击this.configurers.configurePathMatch(configurer)这个方法进去看
protected void configurePathMatch(PathMatchConfigurer configurer) {
this.configurers.configurePathMatch(configurer);
}
点击进去里面居然是循环实现,非常粗暴直接
public void configurePathMatch(PathMatchConfigurer configurer) {
Iterator var2 = this.delegates.iterator();
while(var2.hasNext()) {
WebMvcConfigurer delegate = (WebMvcConfigurer)var2.next();
delegate.configurePathMatch(configurer);
}
}