使用@EnableWebMvc輕松配置Spring MVC
導(dǎo)讀
我們從兩個角度研究@EnableWebMvc:
- @EnableWebMvc的使用
- @EnableWebMvc的底層原理
@EnableWebMvc的使用
@EnableWebMvc需要和java配置類結(jié)合起來才能生效,其實(shí)Spring有好多@Enablexxxx的注解,其生效方式都一樣,通過和@Configuration結(jié)合、使得@Enablexxxx中的配置類(大多通過@Bean注解)注入到Spring IoC容器中。
理解這一配置原則,@EnableWebMvc的使用其實(shí)非常簡單。
我們還是使用前面文章的案例進(jìn)行配置。
新增配置類
在org.example.configuration包下新增一個配置類:
@Configuration
@EnableWebMvc
@ComponentScan({"org.example.controller"})
public class MvcConfiguration{
@Override
public void extendMessageConverters(List<HttpMessageConverter<?>> converters) {
for(HttpMessageConverter httpMessageConverter:converters){
if(StringHttpMessageConverter.class.isAssignableFrom(httpMessageConverter.getClass())){
((StringHttpMessageConverter)httpMessageConverter).setDefaultCharset(Charset.forName("UTF-8"));
}
}
}
}配置類增加controller的包掃描路徑,添加@EnableWebMvc注解,其他不需要干啥。
簡化web.xml
由于使用了@EnableWebMvc,所以web.xml可以簡化,只需要啟動Spring IoC容器、添加DispatcherServlet配置即可
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
id="WebApp_ID" version="3.1">
<!-- 1、啟動Spring的容器-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>applicationContext.xml
Spring IoC容器的配置文件,指定包掃描路徑即可:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:component-scan base-package="org.example">
<context:exclude-filter type="annotation"
expression="org.springframework.stereotype.Controller" />
</context:component-scan>
</beans>Springmvc.xml
springmvc.xml文件也可以簡化,只包含一個視圖解析器及靜態(tài)資源解析的配置即可,其他的都交給@EnableWebMvc即可:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 放行靜態(tài)資源 -->
<mvc:default-servlet-handler />
<!-- 視圖解析器 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 視圖前綴 -->
<property name="prefix" value="/" />
<!-- 視圖后綴 -->
<property name="suffix" value=".jsp" />
</bean>
</beans>測試
添加一個controller:
@Controller
public class HelloWorldController {
@GetMapping(value="/hello")
@ResponseBody
public String hello(ModelAndView model){
return "<h1>@EnableWebMvc 你好</h1>";
}
}啟動應(yīng)用,測試:

發(fā)現(xiàn)有中文亂碼。
解決中文亂碼
參考上一篇文章,改造一下MvcConfiguration配置文件,實(shí)現(xiàn)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<HttpMessageConverter<?>> converters) {
for(HttpMessageConverter httpMessageConverter:converters){
if(StringHttpMessageConverter.class.isAssignableFrom(httpMessageConverter.getClass())){
((StringHttpMessageConverter)httpMessageConverter).setDefaultCharset(Charset.forName("UTF-8"));
}
}
}
}重啟系統(tǒng),測試:

中文亂碼問題已解決。
問題:@EnableWebMvc的作用?
上述案例已經(jīng)可以正常運(yùn)行可,我們可以看到web.xml、applicationContext.xml以及springmvc.xml等配置文件都還在,一個都沒少。
那么@EnableWebMvc究竟起什么作用?
我們?nèi)サ鬇EnableWebMvc配置文件試試看:項(xiàng)目中刪掉MvcConfiguration文件。
重新啟動項(xiàng)目,訪問localhost:8080/hello,報404!
回憶一下MvcConfiguration文件中定義了controller的包掃描路徑,現(xiàn)在MvcConfiguration文件被我們直接刪掉了,controller的包掃描路徑需要以其他方式定義,我們重新修改springmvc.xml文件,把controller包掃描路徑加回來。
同時,我們需要把SpringMVC的注解驅(qū)動配置加回來:
<!-- 掃描包 -->
<context:component-scan base-package="org.example.controller"/>
<mvc:annotation-driven />以上兩行加入到springmvc.xml配置文件中,重新啟動應(yīng)用:

應(yīng)用可以正常訪問了,中文亂碼問題請參考上一篇文章,此處忽略。
因此我們是否可以猜測:@EnableWebMvc起到的作用等同于配置文件中的: <mvc:annotation-driven /> ?
@EnableWebMvc的底層原理
其實(shí)Spring的所有@Enablexxx注解的實(shí)現(xiàn)原理基本一致:和@Configuration注解結(jié)合、通過@Import注解引入其他配置類,從而實(shí)現(xiàn)向Spring IoC容器注入Bean。
@EnableWebMvc也不例外。
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Documented
@Import(DelegatingWebMvcConfiguration.class)
public @interface EnableWebMvc {
}@EnableWebMvc引入了DelegatingWebMvcConfiguration類??匆谎跠elegatingWebMvcConfiguration類,肯定也加了@Configuration注解的:
@Configuration(proxyBeanMethods = false)
public class DelegatingWebMvcConfiguration extends WebMvcConfigurationSupport {
...DelegatingWebMvcConfiguration類擴(kuò)展自WebMvcConfigurationSupport,其實(shí)DelegatingWebMvcConfiguration并沒有創(chuàng)建bean、實(shí)際創(chuàng)建bean的是他的父類WebMvcConfigurationSupport。
WebMvcConfigurationSupport按順序注冊如下HandlerMappings:
RequestMappingHandlerMapping ordered at 0 for mapping requests to annotated controller methods.
HandlerMapping ordered at 1 to map URL paths directly to view names.
BeanNameUrlHandlerMapping ordered at 2 to map URL paths to controller bean names.
HandlerMapping ordered at Integer.MAX_VALUE-1 to serve static resource requests.
HandlerMapping ordered at Integer.MAX_VALUE to forward requests to the default servlet.
并注冊了如下HandlerAdapters:
RequestMappingHandlerAdapter for processing requests with annotated controller methods.
HttpRequestHandlerAdapter for processing requests with HttpRequestHandlers.
SimpleControllerHandlerAdapter for processing requests with interface-based Controllers.
注冊了如下異常處理器HandlerExceptionResolverComposite:
ExceptionHandlerExceptionResolver for handling exceptions through org.springframework.web.bind.annotation.ExceptionHandler methods.
ResponseStatusExceptionResolver for exceptions annotated with org.springframework.web.bind.annotation.ResponseStatus.
DefaultHandlerExceptionResolver for resolving known Spring exception types
以及:
Registers an AntPathMatcher and a UrlPathHelper to be used by:
the RequestMappingHandlerMapping,
the HandlerMapping for ViewControllers
and the HandlerMapping for serving resources
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:
- a ContentNegotiationManager
- a DefaultFormattingConversionService
- an org.springframework.validation.beanvalidation.OptionalValidatorFactoryBean if a JSR-303 implementation is available on the classpath
- a range of HttpMessageConverters depending on the third-party libraries available on the classpath.
總結(jié)
因此,@EnableWebMvc確實(shí)與 <mvc:annotation-driven /> 起到了類似的作用:注冊SpringWebMVC所需要的各種特殊類型的bean到Spring容器中,以便在DispatcherServlet初始化及處理請求的過程中生效!
以上就是使用@EnableWebMvc輕松配置Spring MVC的詳細(xì)內(nèi)容,更多關(guān)于@EnableWebMvc配置Spring MVC的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
log4j2 項(xiàng)目日志組件的實(shí)例代碼
下面小編就為大家分享一篇log4j2 項(xiàng)目日志組件的實(shí)例代碼,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2017-12-12
Java網(wǎng)絡(luò)通信中URL與HTTP編程技術(shù)詳解
要想實(shí)現(xiàn)網(wǎng)絡(luò)編程,除了可以使用Socket之外,我們還可以利用URL編程或HTTP編程技術(shù),所以今天這篇文章,就給大家介紹一下URL編程和HTTP編程技術(shù),看看這兩種技術(shù)有什么特點(diǎn),文中有詳細(xì)的代碼講解,需要的朋友可以參考下2023-11-11
Spring?Boot集成RabbitMQ以及隊(duì)列模式操作
RabbitMQ是實(shí)現(xiàn)AMQP(高級消息隊(duì)列協(xié)議)的消息中間件的一種,下面這篇文章主要給大家介紹了關(guān)于Spring?Boot集成RabbitMQ以及隊(duì)列模式操作的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04
springBoot項(xiàng)目中的全局異常處理和自定義異常處理實(shí)現(xiàn)
異常是由于程序邏輯錯誤、運(yùn)行環(huán)境問題、用戶輸入錯誤等原因?qū)е碌囊环N非正常的狀態(tài)或事件,本文主要介紹了springBoot項(xiàng)目中的全局異常處理和自定義異常處理實(shí)現(xiàn),具有一定的參考價值,感興趣的可以了解一下2024-08-08
java通過AES生成公鑰加密數(shù)據(jù)ECC加密公鑰
這篇文章主要為大家介紹了java通過AES生成公鑰加密數(shù)據(jù)ECC加密公鑰實(shí)現(xiàn)案例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-12-12
如何利用Java實(shí)現(xiàn)MySQL的數(shù)據(jù)變化監(jiān)聽
在高并發(fā)和大數(shù)據(jù)環(huán)境下,實(shí)時獲取?MySQL?數(shù)據(jù)庫的增量變化對數(shù)據(jù)同步、數(shù)據(jù)分析、緩存更新等場景至關(guān)重要,下面我們就來看看如何通過Java實(shí)現(xiàn)MySQL的數(shù)據(jù)變化監(jiān)聽吧2025-02-02

