详解@EnableWebMvc

本文内容纲要:

- @EnableWebMvc注解

- @EnableWebMvc的注释文档说的很详细,先记录第一点,@Import的类是干啥的!

- @EnableWebMvc可扩展的结构

- 想到为什么继承WebMvcConfigurerAdapter或者实现WebMvcConfigurer,就能够在@EnableWebMvc继承上扩展呢?

- @EnableWebMvc导入的是DelegatingWebMvcConfiguration类,和WebMvcConfigurer完全没有联系啊?

- @EnableWebMvc默认是没有静态资源放行的,比如.css .js文件默认 也会被 dispatchServelt / 形式的拦截到

- DefaultServletHttpRequestHandler如何处理静态资源请求?

- 总结@EnableWebMvc替我们做了什么?

最近看了《Spring in Action》的开头,就被Spring注解开发(完全不写web.xml)惊叹了,也第一次知道了@EnableWebMvc是SpringMVC的注解

@EnableWebMvc注解

@EnableWebMvc的javaDoc注释有点长。 从下图得到的几个信息: href="mailto:1.@EnableWebMvc">1.@EnableWebMvc没有任何属性,只是@Import了一个类叫DelegatingWebMvcConfiguration

  1. 注释中说明:将@EnableWebMvc添加给@Configuration类来导入SpringMvc的配置;3.自定义MVC配置,实现接口WebMvcConfigurer或更可能继承WebMvcConfigurerAdapter,并且使用@EnableWebMvc;

4.如果还想要自定义配置,移除@EnableWebMvc,并且继承WebMvcConfigurationSupport或DelegatingWebMvcConfiguration。

5.@EnableWebMvc出现自Spring3.1的版本

image


@EnableWebMvc的注释文档说的很详细,先记录第一点,@Import的类是干啥的!

@Import的多种用法看我这篇文档:Spring @Import . @Import导入了一个类DelegatingWebMvcConfiguration,这个类标注了@Configuration类,这个类下方法上标注了@Bean的都会纳入Spring容器管理。

DelegatingWebMvcConfiguration类如下,但是类里面搜索却没有@Bean标注! 在其父类WebMvcConfigurationSupport里面搜索到了19个@Bean.

这19个@Bean基本上和mvc:annotation-driven/实现的功能无差,甚至提供了一种很便捷的方式扩展mvc:annotation-driven/

image

举两个栗子,说明下:1. mvc:annotation-driven/ @ResponseBody 返回String中文乱码 Spring @ResponseBody String中文乱码

image

@EnableWebMvc同样存在这个问题,默认字符集为ISO-8859-1,解决方案:继承WebMvcConfigurerAdapter,重写extendMessageConverters方法!

image

栗子2:比如需要添加拦截器,原先写法可能是mvc:interceptors</mvc:interceptors>这种形式添加,现在不用XML,方式就是这样:

在继承WebMvcConfigurerAdapter基础上,重写addInterceptor方法。

image


@EnableWebMvc可扩展的结构

图片可以从processOn拷贝,RequestMappingHandlerMapping地址:https://www.processon.com/view/5c9d8480e4b035b243ba651b

RequestMappingHandlerAdapter地址:https://www.processon.com/view/5c9d86cee4b034408de5663d 红框代表可继承扩展WebMvcConfigurerAdapter等扩展的方法。

image

想到为什么继承WebMvcConfigurerAdapter或者实现WebMvcConfigurer,就能够在@EnableWebMvc继承上扩展呢?

@EnableWebMvc导入的是DelegatingWebMvcConfiguration类,和WebMvcConfigurer完全没有联系啊?

image

说明:DelegatingWebMvcConfiguration类,有这样一个属性WebMvcConfigurerComposite,维护着WebMvcConfigurer的集合,有点类似组合模式。

初始化DelegatingWebMvcConfiguration时如果发现了WebMvcConfigurer的实现类,就注入到WebMvcConfigurerComposite中,这样就把我们实现了WebMvcConfigurer的类和@EnableWebMvc联系到一起了,

就可以在mvc:annotation-driven/基础上扩展.

这里很神奇,在我理解中Spring没法自动判断两个Bean作为集合注入的啊! 这里起作用的就是required=false 少了这句话就抛出异常!


@EnableWebMvc默认是没有静态资源放行的,比如.css .js文件默认 也会被 dispatchServelt / 形式的拦截到

原来在web.xml文件中可以这样配置,静态资源后缀为.js .css不拦截

<servlet-mapping>

<servlet-name>default</servlet-name>

<url-pattern>*.html</url-pattern>

<url-pattern>*.htm</url-pattern>

<url-pattern>*.css</url-pattern>

<url-pattern>*.js</url-pattern>

</servlet-mapping>

在没有web.xml的文件中解决方案:继承WebMvcConfigurerAdapter,并且重写configureDefaultServletHandling方法,即可达到和上面一样的效果,就可以访问 .css .js等文件!

image

原理解析:如果这篇博客前面看过了,直接看到WebMvcConfigurationSupport,@Bean注册了一个bean defaultServletHandlerMapping,最终configureDefaultServletHandling会制定我们上面的方法。

image

DefaultServletHandlerConfigurer只是个配置类,Bean实际返回的是hanlderMapping!=null?handlerMapping:new EmptyHandlerMapping(); EmptyHandlerMapping不对请求做任何处理,而configurer的getHandlerMapping方法如下: handler不为空,就会返回一个SimpleUrlHandlerMapping,而configurer.enable()方法等价于configurer.enable(null),就是初始化handler的。总的来说就是,configurer.enable()方法就是注册了一个SimpleUrlHandlerMapping对象,handler就是DefaultServletHttpRequestHandler.

image

image

DefaultServletHttpRequestHandler如何处理静态资源请求?

通过获取 服务器默认的servlet进行转发,因为/** 会匹配所有的URI,所以SimpleUrlHandlerMapping必须放在RequestMappingHandlerMapping之后;核心方式就是servletContext.getNamedDispatcher(“default”).forward(request,response);

image

总结@EnableWebMvc替我们做了什么?

引入了这样一个类DelegatingWebMvcConfiguration,通过@Bean注册了和mvc:annotation-driven/一样的组件,RequestMappingHandlerMapping、RequestMappingHandlerAdatper、HandlerExceptionResolver等等,只要有个Spring管理的bean继承WebMvcConfigurer或WebMvcConfigurerAdapter,重写方法即可自定义mvc:annotation-driven/.

其实@EnableWebMvc == @Import({DelegatingWebMvcConfiguration.class})

本文内容总结:@EnableWebMvc注解,@EnableWebMvc的注释文档说的很详细,先记录第一点,@Import的类是干啥的!,@EnableWebMvc可扩展的结构,想到为什么继承WebMvcConfigurerAdapter或者实现WebMvcConfigurer,就能够在@EnableWebMvc继承上扩展呢?,@EnableWebMvc导入的是DelegatingWebMvcConfiguration类,和WebMvcConfigurer完全没有联系啊?,@EnableWebMvc默认是没有静态资源放行的,比如.css .js文件默认 也会被 dispatchServelt / 形式的拦截到,DefaultServletHttpRequestHandler如何处理静态资源请求?,总结@EnableWebMvc替我们做了什么?,

原文链接:https://www.cnblogs.com/lvbinbin2yujie/p/10624584.html

以上是 详解@EnableWebMvc 的全部内容, 来源链接: utcz.com/z/296254.html

回到顶部