SpringMVC原理剖析――DispatcherServlet的配置

匿名 (未验证) 提交于 2019-12-03 00:41:02

一、如何在代码中配置DispatcherServlet以及其中的原理

DispatcherServlet是SpringMVC的核心,担任着请求分发的责任。

在SpringMVC中配置DispatcherServlet有两种方式:

1. 在Servlet容器的web.xml文件中配置;

2. 用Java代码将DispatcherServlet配置到Servlet容器中

文本主要讲解一下第二种配置方法

首先直接看在代码中如何配置DispatcherServlet

package com.windcloud.config;  import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;  public class FyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {     @Override     protected Class<?>[] getRootConfigClasses() {         return new Class[] { RootConfig.class };     }      //指定配置类     @Override     protected Class<?>[] getServletConfigClasses() {         return new Class[] { WebConfig.class };     }      //将DispatcherServlet映射到“/”     @Override     protected String[] getServletMappings() {         return new String[] { "/" };     } }

通过扩展AbstractAnnotationConfigDispatcherServletInitializer抽象类,可以将DispatcherServletSpring应用上下文配置到Servlet容器中。其原理如下:

Servlet3.0的环境中,即如果Servlet容器遵循的是Servlet3.0接口,那么Servlet容器会在类路径中寻找实现javax.servlet.ServletContainerInitializer接口的类,然后用它来配置Servlet容器。

幸运的是Spring已经为我们提供了这个接口的实现类,名为SpringServletContainerInitializer,在这个类中又会查找WebApplicationInitializer接口的实现类,然后将配置的任务交给这个接口的实现类来完成。

从上面的源码中可以看到,在WebApplicationInitializer接口的onStartup方法中实现在servletContext中加载Servlet.


Spring3.2中引入了WebApplicationInitializer接口的基础实现类(这是一个抽象类),就是AbstractAnnotationConfigDispatcherServletInitializer.但是AbstractAnnotationConfigDispatcherServletInitializer并不是直接实现WebApplicationInitializer接口的,它的实现路径如下:

AbstractAnnotationConfigDispatcherServletInitializer

AbstractAnnotationConfigDispatcherServletInitializer中,给我们留下了三个抽象方法要求我们去实现:

  • AbstractDispatcherServletInitializer 中,这个方法可以将一个或多个路径映射到DispatcherServlet上,如果路径设置为“/”,则所有的请求都会由DispatcherServlet处理。
  • protected abstract Class<?>[] getRootConfigClasses();AbstractAnnotationConfigDispatcherServletInitializer
  • protected abstract Class<?>[] getServletConfigClasses();


所以我们需要写一个继承AbstractAnnotationConfigDispatcherServletInitializer的配置类,如开头的FyWebAppInitializer所示。

下面着重解释一下getRootConfigClasses()和getServletConfigClasses()方法。

在解释这两个方法之前,我们需要知道Spring应用上下文的一些基础知识。

Spring中通常由两个应用上下文:

  • 一个是DispatcherServlet启动的时候创建的上下文(上下文一)

在创建这个上下文的时候会加载配置文件或配置类中声明的bean,getServletConfigClasses返回的配置类(如案例中的WebConfig类)中配置的bean会在这个时候被加载到该上下文中

  • 另一个上下文是由ContextLoaderListener创建的(上下文二)

方法getRootConfigClasses返回的配置类(如案例中的RootConfig类)中配置的bean会被加载到这个上下文中

上面两个上下文的区别是:上下文一中加载的通常是Web组件的bean,如控制器、视图解析器、处理器映射器等。而上下文二中加载的往往是一些中间层和数据层的组件。

其实,在AbstractAnnotationConfigDispatcherServletInitializer中会同时创建DispatcherServletContextLoaderListener.

下面分别给出示例中WebConfigRootConfig的实现

实现如下:

package com.windcloud.config;  import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.ViewResolver; import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; import org.springframework.web.servlet.config.annotation.EnableWebMvc; import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import org.springframework.web.servlet.view.InternalResourceViewResolver;  @Configuration @EnableWebMvc       //启用SpringMVC @ComponentScan("com.windcloud.config")   //启用组件扫描 public class WebConfig extends WebMvcConfigurerAdapter {      //配置JSP视图解析器     @Bean     public ViewResolver viewResolver() {         InternalResourceViewResolver resolver = new InternalResourceViewResolver();         resolver.setPrefix("/WEB-INF/views");         resolver.setSuffix(".jsp");         resolver.setExposeContextBeansAsAttributes(true);         return resolver;     }      //配置静态资源的处理     @Override     public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {         configurer.enable();     } }

实现如下:

package com.windcloud.config;  import org.springframework.context.annotation.ComponentScan; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.FilterType; import org.springframework.web.servlet.config.annotation.EnableWebMvc;  @Configuration @ComponentScan(basePackages = { "com.windcloud.controller" },         excludeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION, value = EnableWebMvc.class)}) public class RootConfig {  }

以上就是关于DispatcherServlet在代码中的配置过程。

二、总结

1. 上述的在代码中配置DispatcherServlet只能在支持Servlet3.0及以上版本的服务器中才可以使用,如Tomcat7及以上,如果版本低于Servlet3.0,那只能在web.xml中配置了

2. 配置DispatcherServlet有三个步骤:

  • 编写继承了AbstractAnnotationConfigDispatcherServletInitializer类的初始化类,并实现其中的三个抽象方法
  • 编写一个配置类(如WebConfig),在该类中配置视图解析器等组件
  • 再编写一个配置类(如RootConfig),在该类中配置扫描路径,通过componentScann可以将service层和dao层组件配置到Spring的上下文中(由ContextLoaderListener创建的上下文)
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!