SpringMVC执行原理解析

目录

一.SpringMVC执行流程解析

二.体系结构UML

三.关键对象介绍

(一)DispatcherServlet

(二)Handler

(三)HandlerMapping

(四)HandlerAdapter

(五)ViewResolver

(六)View

​(七)HandlerExceptionResolver

(八)HandlerInterceptor


一.SpringMVC执行流程解析

  1. 根据request请求URL,循环遍历HandlerMapping列表获取包含HandlerHandlerInterceptorHandlerExecutionChain对象;
  2. 然后通过HandlerExecutionChain对象内部Handler实例循环遍历HandlerAdapter列表获取适配器对象;
  3. 执行HandlerExecutionChain内部的所有拦截器HandlerInterceptorpreHandle方法,成功返回true,返回false直接return;
  4. 如果拦截器preHandle执行成功,再使用HandlerAdapter适配器去执行Handler的业务逻辑并返回一个ModelAndView对象;
  5. 执行所有拦截器postHandle方法;
  6. 通过ModelAndView对象的view属性的值(实际上就是viewName)从ViewResolver集合中获取View对象;
  7. ModelAndViewmodel数据渲染到View返回HTML基于response输出到终端;
  8. 执行所有拦截器的afterCompletion方法;
  9. 上述执行过程中如果出现未主动try catch的异常,都将被HandlerExceptionResolver捕获处理。

二.体系结构UML

 

三.关键对象介绍

(一)DispatcherServlet

继承自HttpServlet实现了对HTTP请求的捕获处理

1. 关键成员属性:

handlerMappings、handlerAdapters、handlerExceptionResolvers和viewResolvers。

/** 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;

/** FlashMapManager used by this servlet */
private FlashMapManager flashMapManager;

/** List of ViewResolvers used by this servlet */
private List<ViewResolver> viewResolvers;

2. 关键成员方法:

  • doDispatch请求调度处理方法:
/**
 * Process the actual dispatching to the handler.
 * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
 * to find the first that supports the handler class.
 * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
 * themselves to decide which methods are acceptable.
 * @param request current HTTP request
 * @param response current HTTP response
 * @throws Exception in case of any kind of processing failure
 */
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception
  • getHandler:返回匹配当前request请求的HandlerExecutionChain执行链对象。
/**
 * Return the HandlerExecutionChain for this request.
 * <p>Tries all handler mappings in order.
 * @param request current HTTP request
 * @return the HandlerExecutionChain, or {@code null} if no handler could be found
 */
protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception
  • getHandlerAdapter:返回适配当前request请求对应Handler的适配器。
/**
 * Return the HandlerAdapter for this handler object.
 * @param handler the handler object to find an adapter for
 * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.
 */
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException
  • processDispatchResult:处理Handler执行结果。
/**
 * Handle the result of handler selection and handler invocation, which is
 * either a ModelAndView or an Exception to be resolved to a ModelAndView.
 */
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
		HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception) throws Exception
  • triggerAfterCompletion:触发执行当前request请求拦截器链的afterCompletion方法。
private void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response,
		HandlerExecutionChain mappedHandler, Exception ex) throws Exception

)Handler

具体业务逻辑的处理器handler

1. 实现方式:

  • 实现Controller接口
public interface Controller {

	/**
	 * Process the request and return a ModelAndView object which the DispatcherServlet
	 * will render. A {@code null} return value is not an error: it indicates that
	 * this object completed request processing itself and that there is therefore no
	 * ModelAndView to render.
	 * @param request current HTTP request
	 * @param response current HTTP response
	 * @return a ModelAndView to render, or {@code null} if handled directly
	 * @throws Exception in case of errors
	 */
	ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception;

}
  • 实现HttpRequestHandler接口
public interface HttpRequestHandler {

	/**
	 * Process the given request, generating a response.
	 * @param request current HTTP request
	 * @param response current HTTP response
	 * @throws ServletException in case of general errors
	 * @throws IOException in case of I/O errors
	 */
	void handleRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException;

}
  • 实现Servlet类
  • 采用@requestMapping注解实现

)HandlerMapping

存储请求URL与处理器Handler对象的映射。

1. 关键成员方法:

  • getHandler:返回一个handler执行链对象,对象包含有Handler和HandlerInterceptor拦截器。
/**
 * Return a handler and any interceptors for this request. The choice may be made
 * on request URL, session state, or any factor the implementing class chooses.
 * <p>The returned HandlerExecutionChain contains a handler Object, rather than
 * even a tag interface, so that handlers are not constrained in any way.
 * For example, a HandlerAdapter could be written to allow another framework's
 * handler objects to be used.
 * <p>Returns {@code null} if no match was found. This is not an error.
 * The DispatcherServlet will query all registered HandlerMapping beans to find
 * a match, and only decide there is an error if none can find a handler.
 * @param request current HTTP request
 * @return a HandlerExecutionChain instance containing handler object and
 * any interceptors, or {@code null} if no mapping found
 * @throws Exception if there is an internal error
 */
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;

2. 接口的实现类

  • BeanNameUrlHandlerMapping:基于Spring IoC容器配置的name属性以“/”开头的Bean实例class属性指定的handler注册到映射。
  • SimpleUrlHandlerMapping:基于手动配置url与handler映射关系的Bean实例注册到映射。
  • RequestMappingHandlerMapping:基于@RequestMapping注解方式实现的handler注册到映射。

(四)HandlerAdapter

执行handler的适配器,SpringMVC采用适配器模式来适配调用指定Handler,根据Handler的不同种类采用不同的Adapter,其Handler与 HandlerAdapter 对应关系如下:

Handler类型

对应的Adapter适配器

说明

Controller

SimpleControllerHandlerAdapter

标准控制器,返回ModelAndView

HttpRequestHandler

HttpRequestHandlerAdapter

业务自行处理请求,不需要通过ModelAndView转到视图

Servlet

SimpleServletHandlerAdapter

基于标准的servlet 处理

HandlerMethod

RequestMappingHandlerAdapter

基于@requestMapping注解方法处理

1. 接口实现类:

2. 关键成员方法:

  • supports:判断当前类型的适配器是否支持传入的Handler对象。
/**
 * Given a handler instance, return whether or not this {@code HandlerAdapter}
 * can support it. Typical HandlerAdapters will base the decision on the handler
 * type. HandlerAdapters will usually only support one handler type each.
 * <p>A typical implementation:
 * <p>{@code
 * return (handler instanceof MyHandler);
 * }
 * @param handler handler object to check
 * @return whether or not this object can use the given handler
 */
boolean supports(Object handler);
  • handler:适配器执行Handler业务逻辑,返回ModelAndView对象或抛出异常。
/**
 * Use the given handler to handle this request.
 * The workflow that is required may vary widely.
 * @param request current HTTP request
 * @param response current HTTP response
 * @param handler handler to use. This object must have previously been passed
 * to the {@code supports} method of this interface, which must have
 * returned {@code true}.
 * @throws Exception in case of errors
 * @return ModelAndView object with the name of the view and the required
 * model data, or {@code null} if the request has been handled directly
 */
ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception;

(五)ViewResolver

视图仓库,存储viewName视图名称与View对象映射关系。

1. 关键成员方法:

  • resolveViewName:匹配viewName,返回对应的View对象。
public interface ViewResolver {

	/**
	 * Resolve the given view by name.
	 * <p>Note: To allow for ViewResolver chaining, a ViewResolver should
	 * return {@code null} if a view with the given name is not defined in it.
	 * However, this is not required: Some ViewResolvers will always attempt
	 * to build View objects with the given name, unable to return {@code null}
	 * (rather throwing an exception when View creation failed).
	 * @param viewName name of the view to resolve
	 * @param locale Locale in which to resolve the view.
	 * ViewResolvers that support internationalization should respect this.
	 * @return the View object, or {@code null} if not found
	 * (optional, to allow for ViewResolver chaining)
	 * @throws Exception if the view cannot be resolved
	 * (typically in case of problems creating an actual View object)
	 */
	View resolveViewName(String viewName, Locale locale) throws Exception;

}

(六)View

具体的视图对象,

1. 关键成员方法:

  • render:渲染Model数据,替换View视图中的表达式。
/**
 * Render the view given the specified model.
 * <p>The first step will be preparing the request: In the JSP case, this would mean
 * setting model objects as request attributes. The second step will be the actual
 * rendering of the view, for example including the JSP via a RequestDispatcher.
 * @param model Map with name Strings as keys and corresponding model
 * objects as values (Map can also be {@code null} in case of empty model)
 * @param request current HTTP request
 * @param response HTTP response we are building
 * @throws Exception if rendering failed
 */
void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) throws Exception;

2. 接口实现类:

(七)HandlerExceptionResolver

异常捕捉器,可以自定义实现自己的全局异常捕捉器。

1. 关键成员方法:

  • resolveException:异常处理方法,返回一个ModelAndView对象。
public interface HandlerExceptionResolver {

	/**
	 * Try to resolve the given exception that got thrown during handler execution,
	 * returning a {@link ModelAndView} that represents a specific error page if appropriate.
	 * <p>The returned {@code ModelAndView} may be {@linkplain ModelAndView#isEmpty() empty}
	 * to indicate that the exception has been resolved successfully but that no view
	 * should be rendered, for instance by setting a status code.
	 * @param request current HTTP request
	 * @param response current HTTP response
	 * @param handler the executed handler, or {@code null} if none chosen at the
	 * time of the exception (for example, if multipart resolution failed)
	 * @param ex the exception that got thrown during handler execution
	 * @return a corresponding {@code ModelAndView} to forward to,
	 * or {@code null} for default processing in the resolution chain
	 */
	ModelAndView resolveException(
			HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex);

}

(八)HandlerInterceptor

Handler拦截器,一个Handler对象可以配置多个拦截器组成拦截器链,拦截器的按照springIoC注册顺序执行。

1. 关键成员方法:

  • preHandle:在Handler处理前执行。
/**
 * Intercept the execution of a handler. Called after HandlerMapping determined
 * an appropriate handler object, but before HandlerAdapter invokes the handler.
 * <p>DispatcherServlet processes a handler in an execution chain, consisting
 * of any number of interceptors, with the handler itself at the end.
 * With this method, each interceptor can decide to abort the execution chain,
 * typically sending a HTTP error or writing a custom response.
 * <p><strong>Note:</strong> special considerations apply for asynchronous
 * request processing. For more details see
 * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
 * @param request current HTTP request
 * @param response current HTTP response
 * @param handler chosen handler to execute, for type and/or instance evaluation
 * @return {@code true} if the execution chain should proceed with the
 * next interceptor or the handler itself. Else, DispatcherServlet assumes
 * that this interceptor has already dealt with the response itself.
 * @throws Exception in case of errors
 */
boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
		throws Exception;
  • postHandle:在Handler处理后执行,只有preHandle方法返回true才会执行本方法。
/**
 * Intercept the execution of a handler. Called after HandlerAdapter actually
 * invoked the handler, but before the DispatcherServlet renders the view.
 * Can expose additional model objects to the view via the given ModelAndView.
 * <p>DispatcherServlet processes a handler in an execution chain, consisting
 * of any number of interceptors, with the handler itself at the end.
 * With this method, each interceptor can post-process an execution,
 * getting applied in inverse order of the execution chain.
 * <p><strong>Note:</strong> special considerations apply for asynchronous
 * request processing. For more details see
 * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
 * @param request current HTTP request
 * @param response current HTTP response
 * @param handler handler (or {@link HandlerMethod}) that started asynchronous
 * execution, for type and/or instance examination
 * @param modelAndView the {@code ModelAndView} that the handler returned
 * (can also be {@code null})
 * @throws Exception in case of errors
 */
void postHandle(
		HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView)
		throws Exception;
  • afterCompletion:在处理完request后执行。
/**
 * Callback after completion of request processing, that is, after rendering
 * the view. Will be called on any outcome of handler execution, thus allows
 * for proper resource cleanup.
 * <p>Note: Will only be called if this interceptor's {@code preHandle}
 * method has successfully completed and returned {@code true}!
 * <p>As with the {@code postHandle} method, the method will be invoked on each
 * interceptor in the chain in reverse order, so the first interceptor will be
 * the last to be invoked.
 * <p><strong>Note:</strong> special considerations apply for asynchronous
 * request processing. For more details see
 * {@link org.springframework.web.servlet.AsyncHandlerInterceptor}.
 * @param request current HTTP request
 * @param response current HTTP response
 * @param handler handler (or {@link HandlerMethod}) that started asynchronous
 * execution, for type and/or instance examination
 * @param ex exception thrown on handler execution, if any
 * @throws Exception in case of errors
 */
void afterCompletion(
		HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
		throws Exception;

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值