赞
踩
servlet中最重要的方法是service方法servlet调用service方法
从FrameworkServlet的service方法开始看
可以看到 如果条件成立 调用processRequest方法 如果条件不成立 调用父类的service方法
其实调用父类的某一个方法 如果子类有重写这个方法 最终调用的还是子类的方法
可以从httpservlet中看到 调用本身的service方法 就是调用doget dopost方法等等
回过头看FrameworkServlet的doget dopost等方法
可以看到调用的还是processRequest这个方法
所以最终调用的都是processRequest方法
进入processRequest方法
可以看到 重点代码只有一行
doService(request, response);
进入doservice方法中
发现doservice方法是abstract抽象的
抽象的方法只能让子类去实现 所以去DispatcherServlet中的doservice方法中
可以发现 重要代码只有一句
doDispatch(request, response);
这个方法就是真正的入口
进入doDispatch(request, response);方法
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. mappedHandler = getHandler(processedRequest); if (mappedHandler == null || mappedHandler.getHandler() == null) { noHandlerFound(processedRequest, response); return; } // Determine handler adapter for the current request. 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()) { logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified); } if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) { return; } } if (!mappedHandler.applyPreHandle(processedRequest, response)) { return; } // Actually invoke the handler. mv = ha.handle(processedRequest, response, mappedHandler.getHandler()); if (asyncManager.isConcurrentHandlingStarted()) { return; } applyDefaultViewName(processedRequest, mv); mappedHandler.applyPostHandle(processedRequest, response, mv); } catch (Exception ex) { dispatchException = ex; } catch (Throwable err) { // As of 4.3, we're processing Errors thrown from handler methods as well, // making them available for @ExceptionHandler methods and other scenarios. dispatchException = new NestedServletException("Handler dispatch failed", err); } processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException); } catch (Exception ex) { triggerAfterCompletion(processedRequest, response, mappedHandler, ex); } catch (Throwable err) { triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", err)); } finally { if (asyncManager.isConcurrentHandlingStarted()) { // Instead of postHandle and afterCompletion if (mappedHandler != null) { mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response); } } else { // Clean up any resources used by a multipart request. if (multipartRequestParsed) { cleanupMultipart(processedRequest); } } } }
上面就是核心代码快
mappedHandler = getHandler(processedRequest);
这行代码 得到了返回的handler
进入getHandler()方法
这段代码是从handlerMappings 中拿到一个handlerMapping后 再来对比当前的请求是哪一个handler 最终返回该handler
handlerMappings 中由springMVC内置了两个handlermapping
这里走了首图中的第二步和第三步 接下来核心控制器DispatcherServlet拿到handler后 执行第四步
执行getHandlerAdapter()方法; handler适配器
进入getHandlerAdapter方法
和上面的getHandler()方法一样
这段代码是从handlerAdapters中拿到一个handlerAdapter后 再来对比当前的请求是哪一个handlerAdapter最终返回该HandlerAdapter
handlerAdapters中由springMVC内置了两个handlerAdapter
然后继续执行代码
执行之前执行拦截器
用得到的handlerAdapter执行handler后返回mv 返回一个视图
最终 通过反射 执行我们自己写的controller中的代码
handlerAdapters和handlerMappings 是在spring-mvc的jar包中配置好的
如果用xml的方式配置controller 就会执行第一个handlermapping
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
如果使用注解的方式 就会执行第二个handlermapping
org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping
所以说 自己实现springMVC中的controller有三种方式 因为有三个HandlerAdapter controller适配器
如果用以前接口的方法去实现spring-mvc的话 就会执行上面两个中的一个
如果用反射的话就会执行最后一个
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter
在DispatcherServlet加载的时候 这个配置文件就已经加载进去了
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。