SpringMVC实现原理

本文详细介绍了SpringMVC的运行原理,从客户端请求到DispatcherServlet,再到HandlerMapping寻找控制器,接着由HandlerAdapter处理请求,再通过ViewResolver解析逻辑视图,最后返回给客户端。同时,深入解析了DispatcherServlet中的关键组件,如HandlerMapping、HandlerAdapter、HandlerExceptionResolver等。
摘要由CSDN通过智能技术生成

一、SpringMVC介绍

        Spring mvc是一个基于mvc的web框架。其中核心类是DispatcherServlet,它是一个Servlet,顶层是实现的Servlet接口。

        Spring mvc是spring框架的一个模块,springmvc和spring无需通过中间整合层进行整合。

二、SpringMVC使用

        需要在web.xml中配置DispatcherServlet。并且需要配置spring监听器ContextLoaderListener

<?xml version="1.0" encoding="UTF-8"?> <!-- 当前的XML文档版本与字符编码 -->
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://java.sun.com/xml/ns/javaee"  xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>SpringMVC</display-name>

  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/classes/spring/applicationContext-*.xml</param-value>
  </context-param>
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <!-- SpringMVC前段控制器 -->
	<servlet>
		<servlet-name>springmvc</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		
		<!-- contextConfigLocation配置SpringMVC加载的配置文件(配置处理器映射器、适配器等等) 
			 如果不配置ContextConfigLocation,默认加载的是/WEB-INF/servlet名称-servlet.xml(springmvc-servlet.xml)
		-->
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>classpath:springmvc-config.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>springmvc</servlet-name>
		<!--
			第一种:*.action,访问以.action结尾由DispatcherServlet进行解析
			第二种:/,所以访问的地址都由DispatcherServlet进行解析,对于静态文件的配置不让DispatcherServlet解析
			第三种:/*,这样配置不对
		-->
		<url-pattern>*.action</url-pattern>
	</servlet-mapping>
	
</web-app>

三、SpringMVC运行原理

1、 运行流程图:

2、流程说明:

(1)客户端(浏览器)发送请求,直接请求到DispatcherServlet。(请求DispatcherServlet)

(2)DispatcherServlet根据请求信息调用处理器映射器HandlerMapping,解析请求对应的Handler。(找到控制器类@Controller)

(3)解析到对应的Handler后,开始由处理器适配器HandlerAdapter处理。(找到@RequestMapping标记的处理方法)

(4)HandlerAdapter会根据Handler来调用真正的处理器来处理请求,并处理相应的业务逻辑。(处理方法中的业务逻辑)

(5)处理器处理完业务后,会返回一个ModelAndView对象,Model是返回的数据对象,View是个逻辑上的View。(返回处理结果)

(6)ViewResolver会根据逻辑View查找实际View。(逻辑视图解析为真正的视图)

(7)DispatcherServlet把返回的Model传给实际View。(DispatcherServlet视图渲染)

(8)通过View返回给请求者(浏览器)

四、DispatcherServlet详细解析

源码分析:

package org.springframework.web.servlet;
 
@SuppressWarnings("serial")
public class DispatcherServlet extends FrameworkServlet {
 
	public static final String MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
	public static final String LOCALE_RESOLVER_BEAN_NAME = "localeResolver";
	public static final String THEME_RESOLVER_BEAN_NAME = "themeResolver";
	public static final String HANDLER_MAPPING_BEAN_NAME = "handlerMapping";
	public static final String HANDLER_ADAPTER_BEAN_NAME = "handlerAdapter";
	public static final String HANDLER_EXCEPTION_RESOLVER_BEAN_NAME = "handlerExceptionResolver";
	public static final String REQUEST_TO_VIEW_NAME_TRANSLATOR_BEAN_NAME = "viewNameTranslator";
	public static final String VIEW_RESOLVER_BEAN_NAME = "viewResolver";
	public static final String FLASH_MAP_MANAGER_BEAN_NAME = "flashMapManager";
	public static final String WEB_APPLICATION_CONTEXT_ATTRIBUTE = DispatcherServlet.class.getName() + ".CONTEXT";
	public static final String LOCALE_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".LOCALE_RESOLVER";
	public static final String THEME_RESOLVER_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_RESOLVER";
	public static final String THEME_SOURCE_ATTRIBUTE = DispatcherServlet.class.getName() + ".THEME_SOURCE";
	public static final String INPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".INPUT_FLASH_MAP";
	public static final String OUTPUT_FLASH_MAP_ATTRIBUTE = DispatcherServlet.class.getName() + ".OUTPUT_FLASH_MAP";
	public static final String FLASH_MAP_MANAGER_ATTRIBUTE = DispatcherServlet.class.getName() + ".FLASH_MAP_MANAGER";
	public static final String EXCEPTION_ATTRIBUTE = DispatcherServlet.class.getName() + ".EXCEPTION";
	public static final String PAGE_NOT_FOUND_LOG_CATEGORY = "org.springframework.web.servlet.PageNotFound";
	private static final String DEFAULT_STRATEGIES_PATH = "DispatcherServlet.properties";
	protected static final Log pageNotFoundLogger = LogFactory.getLog(PAGE_NOT_FOUND_LOG_CATEGORY);
	private static final Properties defaultStrategies;
	static {
		try {
			ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
			defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
		}
		catch (IOException ex) {
			throw new IllegalStateException("Could not load 'DispatcherServlet.properties': " + ex.getMessage());
		}
	}
 
	/** Detect all HandlerMappings or just expect "handlerMapping" bean? */
	private boolean detectAllHandlerMappings = true;
 
	/** Detect all HandlerAdapters or just expect "handlerAdapter" bean? */
	private boolean detectAllHandlerAdapters = true;
 
	/** Detect all HandlerExceptionResolvers or just expect "handlerExceptionResolver" bean? */
	private boolean detectAllHandlerExceptionResolvers = true;
 
	/** Detect all ViewResolvers or just expect "viewResolver" bean? */
	private boolean detectAllViewResolvers = true;
 
	/** Throw a NoHandlerFoundException if no Handler was found to process this request? **/
	private boolean throwExceptionIfNoHandlerFound = false;
 
	/** Perform cleanup of request attributes after include request? */
	private boolean cleanupAfterInclude = true;
 
	/** MultipartResolver used by this servlet */
	private MultipartResolver multipartResolver;
 
	/** LocaleResolver used by this servlet */
	private LocaleResolver localeResolver;
 
	/** ThemeResolver used by this servlet */
	private ThemeResolver themeResolver;
 
	/** List of HandlerMappings used by this servlet */
	private List<HandlerMapping> handlerMappings;
 
	/** List of HandlerAdapters used by this servlet */
	private List<HandlerAdapter> handlerAdapters;
 
	/** List of HandlerExceptionResolvers used by this servlet */
	private List<HandlerExceptionResolver> handlerExceptionResolvers;
 
	/** RequestToViewNameTranslator used by this servlet */
	private RequestToViewNameTranslator viewNameTranslator;
 
	private FlashMapManager flashMapManager;
 
	/** List of ViewResolvers used by this servlet */
	private List<ViewResolver> viewResolvers;
 
	public DispatcherServlet() {
		super();
	}
 
	public DispatcherServlet(WebApplicationContext webApplicationContext) {
		super(webApplicationContext);
	}
	@Override
	protected void onRefresh(ApplicationContext context) {
		initStrategies(context);
	}
 
	protected void initStrategies(ApplicationContext context) {
		initMultipartResolver(context);
		initLocaleResolver(context);
		initThemeResolver(context);
		initHandlerMappings(context);
		initHandlerAdapters(context);
		initHandlerExceptionResolvers(context);
		initRequestToViewNameTranslator(context);
		initViewResolvers(context);
		initFlashMapManager(context);
	}
}

DispatcherServlet类中的属性beans:

1、HandlerMapping:

        用于handlers映射请求和一系列的对于拦截器的前处理和后处理,大部分用@Controller注解。

        HandlerMapping接口的实现类:

                SimpleUrlHandlerMapping类通过配置文件把URL映射到Controller类。

                DefaultAnnotationHandlerMapping类通过注解把URL映射到Controller类。

2、HandlerAdapter:

       帮助DispatcherServlet处理映射请求处理程序的适配器,而不用考虑实际调用的是 哪个处理程序。

        AnnotationMethodHandlerAdapter:通过注解,把请求URL映射到Controller类的方法上。

3、HandlerExceptionResolver:

        处理映射异常。

        SimpleMappingExceptionResolver通过配置文件进行异常处理。

        AnnotationMethodHandlerExceptionResolver:通过注解进行异常处理。

4、ViewResolver:

        根据实际配置解析实际的View类型。

        UrlBasedViewResolver类通过配置文件,把一个视图名交给到一个View来处理。

5、LocaleResolver:

        解决客户正在使用的区域设置以及可能的时区,以便能够提供国际化视野。

6、ThemeResolver:

        解决Web应用程序可以使用的主题,例如提供个性化布局。

7、MultipartResolver:

        解析多部分请求,以支持从HTML表单上传文件。

8、FlashMapManager:

        存储并检索可用于将一个请求属性传递到另一个请求的input和output的FlashMap,通常用于重定向。

1.0.5 从web项目迁移成maven项目 1.0.6 增加菜单框架ext实现,类路径调整 1.0.7 增加http工具类,demo例子 1.0.8 socket工具类,权限组件,菜单组件,jdbc分页支持多种数据库,ant路径工具类,增加jquery easyUI 1.0.9 版本管理,服务根路径工具类,文件上传工具类 1.0.10 集成ueditor在线编辑器 1.0.11 地址联动 1.0.12 Excel工具类 Word工具类 Java NIO实现socket工具类 分布式session jdk升级到1.7 嵌入式redis服务(只支持linux) 1.0.13 修改默认的beanName生成策略,controller参数扩展 1.0.14 分布式session使用zookeeper 1.0.15 zookeeper工具类优化 增加工具类 1.0.16 页面html标志修改 httpclient中文支持 工具类增强(zip,reflect,thread) 1.0.17 ftp服务端和客户端工具类,配置文件maven和web项目路径统一 1.1.0 soapui工具类(web版本) properties等工具类 1.1.1 工具类数据校验 jsp自定义标签 Spring自定义注解 默认requestMapping 1.1.2 代码生成器 1.1.3 首页修改 dateformat.js 时间参数转换 SpringMVC配置文件集中 快递参数接口 1.1.4 des加解密字符串和文件 1.1.5 redis 加锁,redis升级成2.8.2 freemarker工具类 1.1.6 spring websocket 实现在线聊天 maven升级jdk1.8 jetty9.2.4 web升级jdk1.7 tomcat7 1.1.7(maven only) 包名修改 从此不再支持web版本,只支持maven版本 1.1.8 jquery 图片预览插件 图片滚动显示插件 1.1.9 jquery实现鼠标在按钮上显示窗口,离开窗口和按钮时消失 1.1.10 rabbitMQ集成 视频截图 图片缩略图旋转 集成Mybatis 使用数据库连接池druid dubbo使用
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

技术杠精

你的鼓励是我创作最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值