DispatcherServlet的逻辑处理时序图
doDispatch解析
doDispatch函数展示了Spring请求处理所涉及的主要逻辑。
1 | protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception { |
根据request信息查找对应的Handler
在spring中最简单的映射处理器配置如下:
1 | <bean id="simpleUrlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> |
UserController.java如下:
1 | public class UserController extends AbstractController { |
HandlerExecutionChain UML类图
getHandler
1 | /** |
其中,handlerMapping默认值是从DispatcherServlet.properties文件中加载,配置如下:
1 | org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\ |
1 | /** |
根据request查找对应的Handler。如果找不到,就使用默认的Handler1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38//AbstractUrlHandlerMapping.java
/**
* Look up a handler for the URL path of the given request.
* @param request current HTTP request
* @return the handler instance, or {@code null} if none found
*/
protected Object getHandlerInternal(HttpServletRequest request) throws Exception {
String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
Object handler = lookupHandler(lookupPath, request);
if (handler == null) {
// We need to care for the default handler directly, since we need to
// expose the PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE for it as well.
Object rawHandler = null;
if ("/".equals(lookupPath)) {
rawHandler = getRootHandler();
}
if (rawHandler == null) {
rawHandler = getDefaultHandler();
}
if (rawHandler != null) {
// Bean name or resolved handler?
if (rawHandler instanceof String) {
String handlerName = (String) rawHandler;
rawHandler = getApplicationContext().getBean(handlerName);
}
validateHandler(rawHandler, request);
handler = buildPathExposingHandler(rawHandler, lookupPath, lookupPath, null);
}
}
if (handler != null && logger.isDebugEnabled()) {
logger.debug("Mapping [" + lookupPath + "] to " + handler);
}
else if (handler == null && logger.isTraceEnabled()) {
logger.trace("No handler mapping found for [" + lookupPath + "]");
}
return handler;
}
根据URL获取对应的Handler,分为直接匹配和通配符匹配,其中buildPathExPosingHandler函数把Handler封装成HandlerExecutionChain类型。
1 | /** |
构建HandlerExecutionChain对象。
1 | /** |
把配置中的对应拦截器加入到执行链中。
1 | /** |
根据Handler寻找对应的HandlerAdapter
1 | protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException { |
其中,handlerAdapters默认也是从DispatcherServlet.properties中加载:
1 | org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\ |
以SimpleControllerHandlerAdapter为例,
1 |
|
HandlerInterceptor的处理
其各方法执行位置参考doDispatch时序图
逻辑处理 handle
以SimpleControllerHandlerAdapter为例1
2
3
4
5
6
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
return ((Controller) handler).handleRequest(request, response);
}
根据视图跳转页面 render
时序图
解析视图
DispatcherServlet会根据ModelAndView选择合适的视图来进行渲染1
2
3
4
5
6
7
8
9
10
11protected View resolveViewName(String viewName, Map<String, Object> model, Locale locale,
HttpServletRequest request) throws Exception {
for (ViewResolver viewResolver : this.viewResolvers) {
View view = viewResolver.resolveViewName(viewName, locale);
if (view != null) {
return view;
}
}
return null;
}
其中,viewResolvers默认实现:InternalResourceViewResolver,也是从DispatcherServlet.properties中加载:
1 | org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver |
真正生成view对象时在buildView中实现的:
1 | //UrlBasedVeiwResolver.java |
页面跳转
1 | //AbstractView.java |
createMergedOutputModel把将要用到的属性放入mergedModel对象中,renderMergedOutputModel处理页面的跳转
1 | /** |