我们从两个角度研究@EnableWebMvc:
@EnableWebMvc需要和java配置类结合起来才能生效,其实Spring有好多@Enablexxxx的注解,其生效方式都一样,通过和@Configuration结合、使得@Enablexxxx中的配置类(大多通过@Bean注解)注入到Spring IoC容器中。
理解这一配置原则,@EnableWebMvc的使用其实非常简单。
我们还是使用前面文章的案例进行配置。
在org.example.configuration包下新增一个配置类:
@Configuration
@EnableWebMvc
@ComponentScan({"org.example.controller"})
public class MvcConfiguration{
@Override
public void extendMessageConverters(List> converters) {
for(HttpMessageConverter httpMessageConverter:converters){
if(StringHttpMessageConverter.class.isAssignableFrom(httpMessageConverter.getClass())){
((StringHttpMessageConverter)httpMessageConverter).setDefaultCharset(Charset.forName("UTF-8"));
}
}
}
}
配置类增加controller的包扫描路径,添加@EnableWebMvc注解,其他不需要干啥。
由于使用了@EnableWebMvc,所以web.xml可以简化,只需要启动Spring IoC容器、添加DispatcherServlet配置即可
contextConfigLocation
classpath:applicationContext.xml
org.springframework.web.context.ContextLoaderListener
dispatcherServlet
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc.xml
1
dispatcherServlet
/
Spring IoC容器的配置文件,指定包扫描路径即可:
springmvc.xml文件也可以简化,只包含一个视图解析器及静态资源解析的配置即可,其他的都交给@EnableWebMvc即可:
添加一个controller:
@Controller
public class HelloWorldController {
@GetMapping(value="/hello")
@ResponseBody
public String hello(ModelAndView model){
return "@EnableWebMvc 你好
";
}
}
启动应用,测试:
发现有中文乱码。
参考上一篇文章,改造一下MvcConfiguration配置文件,实现WebMvcConfigurer接口、重写其extendMessageConverters方法:
@Configuration
@EnableWebMvc
@ComponentScan({"org.example.controller"})
public class MvcConfiguration implements WebMvcConfigurer{
public MvcConfiguration(){
System.out.println("mvc configuration constructor...");
}
// 通过@EnableWebMVC配置的时候起作用,
@Override
public void extendMessageConverters(List> converters) {
for(HttpMessageConverter httpMessageConverter:converters){
if(StringHttpMessageConverter.class.isAssignableFrom(httpMessageConverter.getClass())){
((StringHttpMessageConverter)httpMessageConverter).setDefaultCharset(Charset.forName("UTF-8"));
}
}
}
}
重启系统,测试:
中文乱码问题已解决。
上述案例已经可以正常运行可,我们可以看到web.xml、applicationContext.xml以及springmvc.xml等配置文件都还在,一个都没少。
那么@EnableWebMvc究竟起什么作用?
我们去掉@EnableWebMvc配置文件试试看:项目中删掉MvcConfiguration文件。
重新启动项目,访问localhost:8080/hello,报404!
回忆一下MvcConfiguration文件中定义了controller的包扫描路径,现在MvcConfiguration文件被我们直接删掉了,controller的包扫描路径需要以其他方式定义,我们重新修改springmvc.xml文件,把controller包扫描路径加回来。
同时,我们需要把SpringMVC的注解驱动配置加回来:
以上两行加入到springmvc.xml配置文件中,重新启动应用:
应用可以正常访问了,中文乱码问题请参考上一篇文章,此处忽略。
因此我们是否可以猜测:@EnableWebMvc起到的作用等同于配置文件中的:
其实Spring的所有@Enablexxx注解的实现原理基本一致:和@Configuration注解结合、通过@Import注解引入其他配置类,从而实现向Spring IoC容器注入Bean。
@EnableWebMvc也不例外。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}
@EnableWebMvc引入了DelegatingWebMvcConfiguration类。看一眼DelegatingWebMvcConfiguration类,肯定也加了@Configuration注解的:
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
...
DelegatingWebMvcConfiguration类扩展自WebMvcConfigurationSupport,其实DelegatingWebMvcConfiguration并没有创建bean、实际创建bean的是他的父类WebMvcConfigurationSupport。
WebMvcConfigurationSupport按顺序注册如下HandlerMappings:
并注册了如下HandlerAdapters:
注册了如下异常处理器HandlerExceptionResolverComposite:
以及:
Registers an AntPathMatcher and a UrlPathHelper to be used by:
Note that those beans can be configured with a PathMatchConfigurer.
Both the RequestMappingHandlerAdapter and the ExceptionHandlerExceptionResolver are configured with default instances of the following by default:
因此,@EnableWebMvc确实与