目录
一.SpringMVC执行流程解析
二.体系结构UML
三.关键对象介绍
(一)DispatcherServlet
(二)Handler
(三)HandlerMapping
(四)HandlerAdapter
(五)ViewResolver
(六)View
(七)HandlerExceptionResolver
(八)HandlerInterceptor
- 根据request请求URL,循环遍历HandlerMapping列表获取包含Handler和HandlerInterceptor的HandlerExecutionChain对象;
- 然后通过HandlerExecutionChain对象内部Handler实例循环遍历HandlerAdapter列表获取适配器对象;
- 执行HandlerExecutionChain内部的所有拦截器HandlerInterceptor的preHandle方法,成功返回true,返回false直接return;
- 如果拦截器preHandle执行成功,再使用HandlerAdapter适配器去执行Handler的业务逻辑并返回一个ModelAndView对象;
- 执行所有拦截器postHandle方法;
- 通过ModelAndView对象的view属性的值(实际上就是viewName)从ViewResolver集合中获取View对象;
- 将ModelAndView中model数据渲染到View返回HTML基于response输出到终端;
- 执行所有拦截器的afterCompletion方法;
- 上述执行过程中如果出现未主动try catch的异常,都将被HandlerExceptionResolver捕获处理。
继承自HttpServlet实现了对HTTP请求的捕获处理
1. 关键成员属性:
handlerMappings、handlerAdapters、handlerExceptionResolvers和viewResolvers。
/** List of HandlerMappings used by this servlet */
private List handlerMappings;
/** List of HandlerAdapters used by this servlet */
private List handlerAdapters;
/** List of HandlerExceptionResolvers used by this servlet */
private List 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 viewResolvers;
2. 关键成员方法:
/**
* Process the actual dispatching to the handler.
* 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.
*
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
/**
* Return the HandlerExecutionChain for this request.
* 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
/**
* 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
/**
* 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
private void triggerAfterCompletion(HttpServletRequest request, HttpServletResponse response,
HandlerExecutionChain mappedHandler, Exception ex) throws Exception
具体业务逻辑的处理器handler
1. 实现方式:
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;
}
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;
}
存储请求URL与处理器Handler对象的映射。
1. 关键成员方法:
/**
* 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.
* 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.
*
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. 接口的实现类
执行handler的适配器,SpringMVC采用适配器模式来适配调用指定Handler,根据Handler的不同种类采用不同的Adapter,其Handler与 HandlerAdapter 对应关系如下:
Handler类型 |
对应的Adapter适配器 |
说明 |
Controller |
SimpleControllerHandlerAdapter |
标准控制器,返回ModelAndView |
HttpRequestHandler |
HttpRequestHandlerAdapter |
业务自行处理请求,不需要通过ModelAndView转到视图 |
Servlet |
SimpleServletHandlerAdapter |
基于标准的servlet 处理 |
HandlerMethod |
RequestMappingHandlerAdapter |
基于@requestMapping注解方法处理 |
1. 接口实现类:
2. 关键成员方法:
/**
* 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.
* A typical implementation:
*
{@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);
/**
* 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;
视图仓库,存储viewName视图名称与View对象映射关系。
1. 关键成员方法:
public interface ViewResolver {
/**
* Resolve the given view by name.
* 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;
}
具体的视图对象,
1. 关键成员方法:
/**
* Render the view given the specified model.
* 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 model, HttpServletRequest request, HttpServletResponse response) throws Exception;
2. 接口实现类:
异常捕捉器,可以自定义实现自己的全局异常捕捉器。
1. 关键成员方法:
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.
* 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);
}
Handler拦截器,一个Handler对象可以配置多个拦截器组成拦截器链,拦截器的按照springIoC注册顺序执行。
1. 关键成员方法:
/**
* Intercept the execution of a handler. Called after HandlerMapping determined
* an appropriate handler object, but before HandlerAdapter invokes the handler.
* 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.
*
Note: 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;
/**
* 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.
* 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.
*
Note: 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;
/**
* 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.
* Note: Will only be called if this interceptor's {@code preHandle}
* method has successfully completed and returned {@code true}!
*
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.
*
Note: 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;