基本介绍
Spring Wev MVC 是基于Sevlet和Spring的一个web框架,名字来源于它的源码
包(spring-webmvc),简称Spring MVC.
对于spring 5.0介绍了一个响应式web框架 Spring Wev Flux,命名来源于源码包名
称(spring-webflux)
核心控制器 DispatcherServlet
- 简介
SpringMvc与其它web框架一样,是围绕中心Servlet设计的一个前端控制器模式,提供
了一个共享算法(dispatcherServlet)来处理请求,然而实际处理者确实通过配置的委
托组件,非常灵活。
DispatcherServlet 与其它 Servlet 一样,根据 Servlet 规范需要在 web.xml
或 java 配置中声明,与此同时,DispatcherServlet 通过 Spring 配置来发现
它需要处理请求的委托组件,如:view resolution、exception handing等
- 注册和初始化
DispatcherServlet
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletCxt) {
// Load Spring web application configuration
AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
ac.register(AppConfig.class);
ac.refresh();
// Create and register the DispatcherServlet
DispatcherServlet servlet = new DispatcherServlet(ac);
ServletRegistration.Dynamic registration = servletCxt.addServlet("app", servlet);
registration.setLoadOnStartup(1);
registration.addMapping("/app/*");
}
}
此外,你也可以直接使用ServletContext API ,你也可以继承
AbstractAnnotationConfigDispatcherServletInitializer 重写它
具体的方法
- Context Hierarchy(上下文层级关系)
DispatcherServlet 由于自己的配置需要一个 WebApplicationContext (是一个
ApplicationContext的继承类),WebApplicationContext与 ServletContxt
和Servlet 建立了一个联系,它同时与ServletContext绑定在一起,对于应用来说,
可以通过 RequestContextUtils 的静态方法来查找他们需要的
WebApplicationContext
Root WebApplicationContext 包含了一些典型的基础的 beans ,如他们需要在多
个servlet中共享的数据仓库、业务层,这些beans能够在子WebApplicationContext
中被重写、重新声明、继承,
-
关系图如下(来自官网):
-
配置
WebApplicationContext
示例:
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class<?>[] { RootConfig.class };
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { App1Config.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/app1/*" };
}
若应用上下文非必须的,则应用可以通过 getRootConfigClasses() 返回所有的配置,
而且 getServletConfigClasses() 返回 null
web.xml
配置
<web-app>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/root-context.xml</param-value>
</context-param>
<servlet>
<servlet-name>app1</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/app1-context.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>app1</servlet-name>
<url-pattern>/app1/*</url-pattern>
</servlet-mapping>
</web-app>
若应用上下文层级非必须的,则应用配置 根上下文 只有一个,或者让参数
contextConfigLocation 的 servlet 参数为空
Special Bean
类型
BeanType | Explanation |
---|---|
HandlerMapping | 匹配一个 request 与一系列interceptors去处理,匹配是基于一些规则的,主要通过HanderMapping的实现有关,主要实现类为RequestMappingHandlerMapping(支持@RequestMapping注解的方法)和 SimpleUrlHandlerMapping (主要维护URL路径中的显示注册处理) |
HandlerAdapter | 帮助DispatcherServlet去请求一个匹配request的hander,不管它实际请求哪个hander,如请求一个注解controller,则需要解析这个注解,而HanderAdapter的目的则是隐藏DispatcherServlet的这些具体细节 |
HandlerExceptionResolver | 处理异常策略,尽可能匹配他们处理的异常,给Html错误视图,或者其它的目标 |
ViewResolver | 从处理请求中解析符合逻辑的字符串实际的视图名称,并提交给响应 |
LocaleResolver, LocaleContextResolver | 尽可能的使用当地的时间区域解析,用来提供一个国际化的视图 |
ThemeResolver | 解析你web程序的主题,提供一个个性化的布局 |
MultipartResolver | 解析多媒体请求(如:浏览器文件上传),帮助多媒体解析库 |
FlashMapManager | 存储和获取request中的请求参数FlashMap,可以用来将参数从一个请求传递到另一个请求,通常为 redirect |
Wev Mvc Config
- 简介
应用可以声明一些用来处理请求的一些基础特殊bean,该DispatcherServlet将会在
WebApplicationContext中查找这些beans,如果没有找到,则会回调在同级目录下
DispatcherServlet.propperties 文件中列出的默认类型 bean
- Servlet Config
在Servlet 3.0+环境中,可以选择如下或与web.xml中结合来配置
import org.springframework.web.WebApplicationInitializer;
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
XmlWebApplicationContext appContext = new XmlWebApplicationContext();
appContext.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
ServletRegistration.Dynamic registration = container.addServlet("dispatcher", new DispatcherServlet(appContext));
registration.setLoadOnStartup(1);
registration.addMapping("/");
}
}
WebApplicationInitializer
介绍
WebApplicationInitializer 是 SpringMvc 提供的一个接口,用来确保你的实现
类在Servlet 3 容器中能够被检测到,并自动初始化。有一个
WebApplicationInitializer的抽象类为 AbstractDispatcherServletInitializer
用来简化 DispatcherServlet 的注册,通过重写具体的映射和配置文件的位置方法
- 基于
Java
配置
public class MyWebAppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return null;
}
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class<?>[] { MyWebConfig.class };
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
- 基于
XML
的配置
public class MyWebAppInitializer extends AbstractDispatcherServletInitializer {
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
@Override
protected WebApplicationContext createServletApplicationContext() {
XmlWebApplicationContext cxt = new XmlWebApplicationContext();
cxt.setConfigLocation("/WEB-INF/spring/dispatcher-config.xml");
return cxt;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
上述均翻译自官方文档