上一篇讲到
1.spring容器和spirngmvc容器都已经启动了
2.DispatchServlet也在servlet容器加载了
接下来看下springmvc是如何加载我们配置类中的信息的
大体流程 :
1.WebMvcConfigurationSupport 作为组件配置工厂
1.1 @bean HandlerMapping
1.1.1 加入拦截器
1.1.2 加入跨域配置
......
1.2 @bean HandlerAdapter
......这些类会在处理请求时用到
主要工作就是用@Bean的方式将一些组件注册到spring容器中
一. springmvc 自定义配置类详解
通常我们在基于注解的springmvc中,会用一个配置类来代替springmvc.xml的工作:配置拦截器,视图解析路径等等 有两种配置方式:
第一种配置方式:
- 配置类上@EnableWebMvc,@Configuration
- 继承WebMvcConfigurerAdapter
@Configuration
@EnableWebMvc
public class AppConfig extends WebMvcConfigurerAdapter {
@Autowired
private UserInterceptor userInterceptor;
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/views/", ".jsp");
}
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(userInterceptor).addPathPatterns("/user/**").excludePathPatterns("/user/query/**");
registry.addInterceptor(new UserInterceptor1()).addPathPatterns("/user/**").excludePathPatterns("");
super.addInterceptors(registry);
}
}
第二种配置方式
- 配置类上@Configuration
- 继承WebMvcConfigurationSupport类,重写方法
为啥要这样组合着来配置,并且两种都可以?
这里其实最重要的类是WebMvcConfigurationSupport类,他里面有很多@Bean方法,注册了springmvc的组件,如HandleMapping,HandleAdapter。 两种配置方式其实都要触发WebMvcConfigurationSupport类的@Bean方法
第一种详解
1. @EnableWebMvc注解
这个注解类用@Import注解导入了DelegatingWebMvcConfiguration这个类
DelegatingWebMvcConfiguration 继承了WebMvcConfigurationSupport,并且类上有@Configuration注解,那么他会触发类中,从WebMvcConfigurationSupport类继承而来的这些带有@Bean的方法,比如
2.继承WebMvcConfigurerAdapter
这步其实主要是为了重写WebMvcConfigurerAdapter里面的方法,并且作为WebMvcConfigurer的实现类。
DelegatingWebMvcConfiguration会把配置类作为WebMvcConfigurer的子类装到configurers的集合中
后续DelegatingWebMvcConfiguration触发HandlerMapping的@Bean时,获取拦截器时,是循环上面这个集合,调用他们的addInterceptors方法来实现的。
也就是说触发springmvc组件的@Bean操作不是由配置类来触发的,而是由@EnableWebMvc中的DelegatingWebMvcConfiguration类来完成,并且把我们的配置方法这个类的容器中,配置类中的注册的东西由它来调配置类中的方法来完成
第二种详解
@Configuration + 继承WebMvcConfigurationSupport 这种方式就是直接由我们的配置类来触发springmvc组件@Bean方法
获取拦截器的话,直接就调用自己重写的addInterceptors方法就行了
关于第一种方式中WebMvcConfigurerAdapter被弃用的解决办法
在类上已经存在了@Deprecated注解,表示弃用
并且注释中作者表示,5.0之后这个类被弃用,但是同时也说明了解决办法,叫我们直接实现它的接口WebMvcConfigurer就行。
而我们前面讲到的第一种配置方式,在DelegatingWebMvcConfiguration中获取配置类其实是获取WebMvcConfigurer接口的实现类,所以配置类换成直接实现WebMvcConfigurer接口,不继承WebMvcConfigurerAdapter类来间接实现这个接口 是没有任何问题的
二. springmvc 组件注册:
上面讲到这两种配置方式都会触发spirngmvc组件的加载,那么我们来看下到底注册了哪些组件到spring容器中。
- RequestMappingHandlerAdapter
作用:
1. 拦截器配置
2. 跨域配置
3. 统一后缀啥的
2. RequestMappingHandlerAdapter
作用:
1. 消息转化器
2. 传入参数解析器
3. 返回值解析器
3........还有很多,就不赘述了
主要的工作其实就是将一些组件注册到spring容器中而已,包括我们在配置类中自定义的一些组件。后续DispatchServlet会直接从spring容器里面拿,放到自己的类中