码迷,mamicode.com
首页 > Web开发 > 详细

SprngMVC源码学习

时间:2017-08-03 13:58:41      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:this   async   技术   protected   pos   control   style   主题   mode   

 

运行helloWorld示例进入调试界面。 

 

技术分享

 DispatcherServlet:前端控制器

DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse) line: 945    
DispatcherServlet.doService(HttpServletRequest, HttpServletResponse) line: 876    
DispatcherServlet(FrameworkServlet).processRequest(HttpServletRequest, HttpServletResponse) line: 931    
DispatcherServlet(FrameworkServlet).doGet(HttpServletRequest, HttpServletResponse) line: 822    
DispatcherServlet(HttpServlet).service(HttpServletRequest, HttpServletResponse) line: 624    
DispatcherServlet(FrameworkServlet).service(HttpServletRequest, HttpServletResponse) line: 807    
DispatcherServlet(HttpServlet).service(ServletRequest, ServletResponse) line: 731    

由上进入源码查看

DispatcherServlet(FrameworkServlet).service(HttpServletRequest, HttpServletResponse) line: 807
public abstract class FrameworkServlet extends HttpServletBean implements ApplicationContextAware {
  ...
service();
}

  

HttpServletBean 的实现
public abstract class HttpServletBean extends HttpServlet implements EnvironmentCapable, EnvironmentAware {}

 技术分享

 

 接下来重点关注doDispatch()

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        boolean multipartRequestParsed = false;

        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

        try {
            ModelAndView mv = null;
            Exception dispatchException = null;

            try {
                processedRequest = checkMultipart(request);
                multipartRequestParsed = processedRequest != request;

                // Determine handler for the current request.
                //1、根据当前请求地址找到哪个处理器来处理请求
                mappedHandler = getHandler(processedRequest);
                if (mappedHandler == null || mappedHandler.getHandler() == null) {
                     //2、如果找不到报错
                    noHandlerFound(processedRequest, response);
                    return;
                }

                // Determine handler adapter for the current request.
                //2\为当前请求确定适配器
                HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

                // Process last-modified header, if supported by the handler.
                String method = request.getMethod();
                boolean isGet = "GET".equals(method);
                if (isGet || "HEAD".equals(method)) {
                    long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                    if (logger.isDebugEnabled()) {
                        String requestUri = urlPathHelper.getRequestUri(request);
                        logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
                    }
                    if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
                        return;
                    }
                }

                if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                    return;
                }

                try {
                    // Actually invoke the handler.
                    //真正执行方法
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                }
                finally {
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }
                }

                applyDefaultViewName(request, mv);
                mappedHandler.applyPostHandle(processedRequest, response, mv);
            }
            catch (Exception ex) {
                dispatchException = ex;
            }
            //处理响应结果
            processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
        }
        catch (Exception ex) {
            triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
        }
        catch (Error err) {
            triggerAfterCompletionWithError(processedRequest, response, mappedHandler, err);
        }
        finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                // Instead of postHandle and afterCompletion
                mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                return;
            }
            // Clean up any resources used by a multipart request.
            if (multipartRequestParsed) {
                cleanupMultipart(processedRequest);
            }
        }
    }
四步:
1)、所有请求进来都经过DispatcherServlet的900:doDispatch()方法(包含了处理请求以及响应的所有流程)
2)、916;getHandler(processedRequest);根据当前请求获取到能处理这个请求的Controller对象
3)、923:找到能执行这个Controller对象里面每一个方法的适配器
4)、945:ha.handle适配器调用目标方法(利用反射调用方法)
5)、959:转发到页面(处理响应结果)processDispatchResult
 
 
1、根据当前请求地址找到哪个处理器来处理请求
                mappedHandler = getHandler(processedRequest);

protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		for (HandlerMapping hm : this.handlerMappings) {
			if (logger.isTraceEnabled()) {
				logger.trace(
						"Testing handler map [" + hm + "] in DispatcherServlet with name ‘" + getServletName() + "‘");
			}
			HandlerExecutionChain handler = hm.getHandler(request);
			if (handler != null) {
				return handler;
			}
		}
		return null;
	}

  

技术分享

 

SpringfMVC启动的时候扫描所有的注解,将每一个类的每一个方法能处理什么请求都已经保存在handlerMapping中了;DefaultAnnotationHandlerMapping;
技术分享
2、为当前请求确定适配器
 HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
找到能调用这个类里面每个方法的适配器;适配器利用反射调用方法;
 
protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		for (HandlerAdapter ha : this.handlerAdapters) {
			if (logger.isTraceEnabled()) {
				logger.trace("Testing handler adapter [" + ha + "]");
			}
			if (ha.supports(handler)) {
				return ha;
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
	}

  

我们都使用注解模式的所以适配器使用第三个;
技术分享

 

3、SpringMVC中DispatcherServlet的几个重要属性,以及赋值
SpringMVC九大组件;
 
/** 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;

    /** FlashMapManager used by this servletFlashMap 管理器 */
    private FlashMapManager flashMapManager;

    /** List of ViewResolvers used by this servlet视图解析器 */
    private List<ViewResolver> viewResolvers;

 

技术分享
技术分享
技术分享
技术分享
文件上传组件默认没值;
默认赋值;
    protected void initStrategies(ApplicationContext context) {
         //默认从ioc容器中获取id为multipartResolver的组件,如果没有获取到就赋值为null
        initMultipartResolver(context);
         //按照id获取localeResolver;如果没有;
        initLocaleResolver(context);
        initThemeResolver(context);
        initHandlerMappings(context);
        initHandlerAdapters(context);
        initHandlerExceptionResolvers(context);
        initRequestToViewNameTranslator(context);
        initViewResolvers(context);
        initFlashMapManager(context);
    }
 
//1、有些组件是这么》?先获取用户配置的,如果没有可以使用默认的(MultipartResolver )
//2、有些组件是拿id获取的;有些是拿类型获取的,
//3、给SpringMVC中配置九大之一的某个组件;如果是拿id‘获取的?id不要乱写,用指定id;
//如果是用类型获取,id可以不用写;
     
 
 
在于DispatcherServlet.class同目录下有一个properties文件,这里封装了所有组件默认的类型;
 
 

SprngMVC源码学习

标签:this   async   技术   protected   pos   control   style   主题   mode   

原文地址:http://www.cnblogs.com/limingxian537423/p/7279021.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!