文章目录
一、配置Spring MVC
(一)Xml配置
- 配置 DispatcherServlet
<web-app>
<display-name>SpringMVC</display-name>
<!--业务层和持久层的spring配置文件,被父容器所使用-->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:spring-context.xml</param-value>
</context-param>
<!--配置 DispatcherServlet -->
<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*:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<!--初始化父上下文容器-->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
- 父上下文容器配置
spring-context.xml
<beans>
<!-- 注解扫描包,不扫描Controller控制器 -->
<context:component-scan base-package="com.learning.springmvc.base.xml">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
</beans>
- DispatcherServlet 上下文容器配置
spring-mvc.xml
<beans>
<!-- 注解扫描包,只扫描Controller控制器,需要设置use-default-filters为false -->
<context:component-scan base-package="com.learning.springmvc.base.xml" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
</context:component-scan>
<!-- 配置视图解析器,设置 前缀+ viewName +后缀 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
<property name="applicationContext" value="cxf"/>
</bean>
</beans>
(二)JavaConfig配置(Servlet3.x)
- 配置 DispatcherServlet
public class WebMvcInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[]{ApplicationConfig.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[]{WebMvcConfig.class};
}
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
}
- 应用级上下文容器配置
@Configuration
@ComponentScan(basePackages = {"com.learning.springmvc.base.javaconfig"},
excludeFilters = {@ComponentScan.Filter(classes = Controller.class)})
public class ApplicationConfig {
}
- DispatcherServlet (Web)上下文容器配置
- 实现
WebMvcConfigurerAdapter
类(5.x 以后直接实现WebMvcConfigurer
) @ComponentScan
自动扫描@EnableWebMvc
注解启动Spring MVC自定义扩展组件装配
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.learning.springmvc.base.javaconfig", useDefaultFilters = false,
includeFilters = {@ComponentScan.Filter(classes = Controller.class)})
public class WebMvcConfig extends WebMvcConfigurerAdapter {
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp("/WEB-INF/pages/", ".jsp");
}
}
(三)Servlet3.x 配置实现分析
javax.servlet.ServletContainerInitializer
是 Servlet3.x 新增的一个接口,容器在启动时使用 JAR 服务 API(JAR Service API) 来发现ServletContainerInitializer
的实现类,并且容器将WEB-INF/lib
目录下 JAR 包中的类都交给该类的 onStartup() 方法处理
- 实现
ServletContainerInitializer
生效方法:/META-INF/services/javax.servlet.ServletContainerInitializer
文件配置实现类的全路径类名 - 该实现类上使用
@HandlesTypes
注解来指定希望被处理的类,过滤掉不希望给onStartup()
处理的类
- 在Spring 中
org.springframework.web.SpringServletContainerInitializer
类实现了ServletContainerInitializer
接口
/META-INF/services/javax.servlet.ServletContainerInitializer
配置内容为:org.springframework.web.SpringServletContainerInitializer
@HandlesTypes
标注org.springframework.web.WebApplicationInitializer
接口,即查找实现了该接口的类(@HandlesTypes注解功能),并将配置任务交给这些实现类完成。
- 在Spring中提供了一个便利的类
org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer
,该类实现了WebApplicationInitializer
接口,并且做了大量的初始化工作,使得在初始化Web应用容器时只需要简单的指定容器配置类以及servlet映射即可。
- 可以指定两个上下文容器:
RootApplicationContext
、ServletApplicationContext
RootApplicationContext
:业务层和持久层的的容器(Spring 容器)ServletApplicationContext
:控制层的容器 (Spring Web Mvc 容器)
具体 ContextLoaderListener
、DispatcherServlet
如何被注册以及初始化的过程分析,Spring 上下文容器初始化、Spring MVC 上下文容器初始化
二、JavaConfig配置实现解析
- Spring MVC 定制配置类,需要继承
WebMvcConfigurerAdapter
类(5.x 以后直接实现WebMvcConfigurer
接口),并在此类使用@EnableWebMvc
注解。 - 重写
WebMvcConfigurerAdapter
类的方法,即可完成Spring MVC 的常用功能。
(一)配置实现分析
- 在 SpringMVC4.x 笔记(1):框架体系概述 中,已经分析了
@EnableWebMvc
的功能,其功能实现类DelegatingWebMvcConfiguration
继承自WebMvcConfigurationSupport
,其不在赘述。 DelegatingWebMvcConfiguration
内部有一个类型为WebMvcConfigurerComposite
的属性configurers
,所有的功能都是通过这个属性完成的。WebMvcConfigurerComposite
类实现了WebMvcConfigurer
接口,即WebMvcConfigurerAdapter
实现的接口。具体类图如下:
(二)扩展实现的功能列表
WebMvcConfigurerAdapter
类中提供了大量的方法用于自定义扩展实现,列表如下:
方法名称 | 描述 |
---|---|
configurePathMatch | 定制URL路径的匹配规则 |
configureContentNegotiation | 配置动态视图处理 |
configureAsyncSupport | 配置异步支持 |
configureDefaultServletHandling | 默认的 HandlerMapping 配置 |
addFormatters | 配置格式化工具,Formatter、Converter。 |
addInterceptors | 配置拦截器 |
addResourceHandlers | 配置静态资源 |
addCorsMappings | CORS 配置 |
addViewControllers | 简单视图控制器 |
configureViewResolvers | 配置视图解析器 |
addArgumentResolvers | 配置方法参数解析器 |
addReturnValueHandlers | 配置返回值解析器 |
configureMessageConverters | 消息转换器,覆盖。 |
extendMessageConverters | 消息转换器。仅仅添加一个自定义的HttpMessageConverter,不会覆盖 |
configureHandlerExceptionResolvers | 配置处理异常解析器,会覆盖。 |
extendHandlerExceptionResolvers | 配置处理异常解析器,只是添加,不会覆盖。 |
getValidator | 配置验证 |
getMessageCodesResolver | 数据绑定。默认是DefaultMessageCodesResolver ,将代码解析成错误消息。 |
- 可以参考SpringBoot的Web自动配置类
WebMvcAutoConfiguration
,会有进一步的理解。 - 具体功能组件的使用,可以见后续博客分享。