一、配置Spring MVC

(一)Xml配置

  1. 配置 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>
  1. 父上下文容器配置 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>
  1. 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)

  1. 配置 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[]{"/"};
    }

}

  1. 应用级上下文容器配置
@Configuration
@ComponentScan(basePackages = {"com.learning.springmvc.base.javaconfig"},
        excludeFilters = {@ComponentScan.Filter(classes = Controller.class)})
public class ApplicationConfig {
}
  1. 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 配置实现分析

  1. 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() 处理的类
  1. 在Spring 中 org.springframework.web.SpringServletContainerInitializer类实现了ServletContainerInitializer接口
  • /META-INF/services/javax.servlet.ServletContainerInitializer 配置内容为:org.springframework.web.SpringServletContainerInitializer
  • @HandlesTypes 标注org.springframework.web.WebApplicationInitializer接口,即查找实现了该接口的类(@HandlesTypes注解功能),并将配置任务交给这些实现类完成。

在这里插入图片描述

  1. 在Spring中提供了一个便利的类org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer,该类实现了WebApplicationInitializer接口,并且做了大量的初始化工作,使得在初始化Web应用容器时只需要简单的指定容器配置类以及servlet映射即可。
  • 可以指定两个上下文容器:RootApplicationContextServletApplicationContext
  • RootApplicationContext:业务层和持久层的的容器(Spring 容器)
  • ServletApplicationContext:控制层的容器 (Spring Web Mvc 容器)
    在这里插入图片描述

具体 ContextLoaderListenerDispatcherServlet 如何被注册以及初始化的过程分析,Spring 上下文容器初始化Spring MVC 上下文容器初始化

二、JavaConfig配置实现解析

  1. Spring MVC 定制配置类,需要继承WebMvcConfigurerAdapter类(5.x 以后直接实现 WebMvcConfigurer接口),并在此类使用@EnableWebMvc注解。
  2. 重写WebMvcConfigurerAdapter类的方法,即可完成Spring MVC 的常用功能。

(一)配置实现分析

  1. SpringMVC4.x 笔记(1):框架体系概述 中,已经分析了@EnableWebMvc的功能,其功能实现类 DelegatingWebMvcConfiguration继承自WebMvcConfigurationSupport,其不在赘述。
  2. DelegatingWebMvcConfiguration 内部有一个类型为WebMvcConfigurerComposite的属性configurers,所有的功能都是通过这个属性完成的。WebMvcConfigurerComposite类实现了WebMvcConfigurer接口,即WebMvcConfigurerAdapter实现的接口。具体类图如下:

在这里插入图片描述

(二)扩展实现的功能列表

  1. 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,将代码解析成错误消息。
  1. 可以参考SpringBoot的Web自动配置类WebMvcAutoConfiguration,会有进一步的理解。
  2. 具体功能组件的使用,可以见后续博客分享。

参考

  1. 官方文档
  2. 笔记源码
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐