springmvc框架原理:
1、用户发送请求至前端控制器DispatcherServlet
2、DispatcherServlet收到请求调用HandlerMapping处理器映射器查找Handler。
3、处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
4、DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
5、HandlerAdapter调用处理器Handler
6、Handler执行完成返回ModelAndView
7、HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet
8、DispatcherServlet将ModelAndView传给ViewReslover视图解析器,ViewReslover根据逻辑视图名解析View
9、ViewReslover返回View
10、DispatcherServlet对View进行渲染视图(即将模型数据填充至request域)。
11、DispatcherServlet响应用户
DispatcherServlet前端控制器(springmvc框架提供)
作用:接收请求,响应结果
有了前端控制器减少各各组件之间的耦合性,前端控制器相当于中央调度器。
当一个请求(request)过来,进入DispatcherServlet中,里面有个方法叫 doDispatch方法 里面包含了核心流程
protected void doDispatch(HttpServletRequest request, HttpServletResponse response)
/* */ throws Exception
/* */ {
/* 917 */ HttpServletRequest processedRequest = request;
/* 918 */ HandlerExecutionChain mappedHandler = null;
/* 919 */ boolean multipartRequestParsed = false;
/* */
/* 921 */ WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
/* */ try
/* */ {
/* 924 */ ModelAndView mv = null;
/* 925 */ Exception dispatchException = null;
/* */ try
/* */ {
/* 928 */ processedRequest = checkMultipart(request);
/* 929 */ multipartRequestParsed = processedRequest != request;
/* */
/* */
/* 932 */ mappedHandler = getHandler(processedRequest);//处理器调用链, 包含了 处理器对象 以及和处理器相关的 拦截器。 有目标方法 和 Handler
/* 933 */ if ((mappedHandler == null) || (mappedHandler.getHandler() == null)) {
/* 934 */ noHandlerFound(processedRequest, response);
/* 935 */ return;
/* */ }
getHandler(processedRequest)获得HandlerExecutionChain (其实是从HandlerMapping 中获得的)
protected HandlerExecutionChain getHandler(HttpServletRequest request)
/* */ throws Exception
/* */ {
/* 1115 */ for (HandlerMapping hm : this.handlerMappings) {
/* 1116 */ if (this.logger.isTraceEnabled()) {
/* 1117 */ this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name '" +
/* 1118 */ getServletName() + "'");
/* */ }
/* 1120 */ HandlerExecutionChain handler = hm.getHandler(request);
/* 1121 */ if (handler != null) {
/* 1122 */ return handler;
/* */ }
/* */ }
/* 1125 */ return null;
/* */ }
//初始化所有的handlerMapping
private void initHandlerMappings(ApplicationContext context)
/* */ {
/* 563 */ this.handlerMappings = null;
/* */
/* 565 */ if (this.detectAllHandlerMappings)
/* */ {
/* */
/* 568 */ Map<String, HandlerMapping> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
/* 569 */ if (!matchingBeans.isEmpty()) {
/* 570 */ this.handlerMappings = new ArrayList(matchingBeans.values());
/* */
/* 572 */ AnnotationAwareOrderComparator.sort(this.handlerMappings);
/* */ }
/* */ }
/* */ else {
/* */ try {
/* 577 */ HandlerMapping hm = (HandlerMapping)context.getBean("handlerMapping", HandlerMapping.class);
/* 578 */ this.handlerMappings = Collections.singletonList(hm);
/* */ }
/* */ catch (NoSuchBeanDefinitionException localNoSuchBeanDefinitionException) {}
/* */ }
继续
1.url请求路径不存在通过noHandlerFound方法返回404
if ((mappedHandler == null) || (mappedHandler.getHandler() == null)) {
/* 934 */ noHandlerFound(processedRequest, response);//返回404
/* 935 */ return;
/* */ }
protected void noHandlerFound(HttpServletRequest request, HttpServletResponse response)
/* */ throws Exception
/* */ {
/* 1135 */ if (pageNotFoundLogger.isWarnEnabled()) {
/* 1136 */ pageNotFoundLogger.warn("No mapping found for HTTP request with URI [" + getRequestUri(request) + "] in DispatcherServlet with name '" +
/* 1137 */ getServletName() + "'");
/* */ }
/* 1139 */ if (this.throwExceptionIfNoHandlerFound)
/* */ {
/* 1141 */ throw new NoHandlerFoundException(request.getMethod(), getRequestUri(request), new ServletServerHttpRequest(request).getHeaders());
/* */ }
/* */
/* 1144 */ response.sendError(404);
/* */ }
2.存在
通过getHandlerAdapter得到HandlerAdapter处理器适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
protected HandlerAdapter getHandlerAdapter(Object handler)
/* */ throws ServletException
/* */ {//通过initHandlerAdapters初始化得到HandlerAdapter
/* 1154 */ for (HandlerAdapter ha : this.handlerAdapters) {
/* 1155 */ if (this.logger.isTraceEnabled()) {
/* 1156 */ this.logger.trace("Testing handler adapter [" + ha + "]");
/* */ }
/* 1158 */ if (ha.supports(handler)) {
/* 1159 */ return ha;
/* */ }
/* */ }
/* 1162 */ throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
/* */ }
/* */ private void initHandlerAdapters(ApplicationContext context)
/* */ {
/* 601 */ this.handlerAdapters = null;
/* */
/* 603 */ if (this.detectAllHandlerAdapters)
/* */ {
/* */
/* 606 */ Map<String, HandlerAdapter> matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerAdapter.class, true, false);
/* 607 */ if (!matchingBeans.isEmpty()) {
/* 608 */ this.handlerAdapters = new ArrayList(matchingBeans.values());
/* */
/* 610 */ AnnotationAwareOrderComparator.sort(this.handlerAdapters);
/* */ }
/* */ }
/* */ else {
/* */ try {
/* 615 */ HandlerAdapter ha = (HandlerAdapter)context.getBean("handlerAdapter", HandlerAdapter.class);
/* 616 */ this.handlerAdapters = Collections.singletonList(ha);
/* */ }
/* */ catch (NoSuchBeanDefinitionException localNoSuchBeanDefinitionException) {}
/* */ }
/* 625 */ if (this.handlerAdapters == null) {
/* 626 */ this.handlerAdapters = getDefaultStrategies(context, HandlerAdapter.class);
/* 627 */ if (this.logger.isDebugEnabled()) {
/* 628 */ this.logger.debug("No HandlerAdapters found in servlet '" + getServletName() + "': using default");
/* */ }
/* */ }
/* */
继续执行
//调用HandlerExecutionChain中的applyPreHandle方法执行拦截器的方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
/* 955 */ return;
/* */ }
/* */ boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response)
/* */ throws Exception
/* */ {
/* 130 */ HandlerInterceptor[] interceptors = getInterceptors();//得到拦截器
/* 131 */ if (!ObjectUtils.isEmpty(interceptors)) {
/* 132 */ for (int i = 0; i < interceptors.length; i++) {
/* 133 */ HandlerInterceptor interceptor = interceptors[i];
//preHandle执行拦截器
/* 134 */ if (!interceptor.preHandle(request, response, this.handler)) {
/* 135 */ triggerAfterCompletion(request, response, null);
/* 136 */ return false;
/* */ }
/* 138 */ this.interceptorIndex = i;
/* */ }
/* */ }
/* 141 */ return true;
/* */ }
继续执行得到modelandview
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
ha.handle会根据具体的配置去找执行对应的处理器适配器(最终调用的是HttpRequestHandlerAdapter中的)执行handle,返回modelandview
继续执行
/* 965 */ applyDefaultViewName(processedRequest, mv);
/* 966 */ mappedHandler.applyPostHandle(processedRequest, response, mv);// 拦截器的 PostHandler方法
/* */ }
/* */ catch (Exception ex) {
/* 969 */ dispatchException = ex;
/* */ }
/* 971 */ processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);//该方法最终进行视图解析并渲染
/* */ }
private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception)
/* */ throws Exception
/* */ {
/* 1011 */ boolean errorView = false;
/* */
/* 1013 */ if (exception != null) {
/* 1014 */ if ((exception instanceof ModelAndViewDefiningException)) {
/* 1015 */ this.logger.debug("ModelAndViewDefiningException encountered", exception);
/* 1016 */ mv = ((ModelAndViewDefiningException)exception).getModelAndView();
/* */ }
/* */ else {
/* 1019 */ Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
/* 1020 */ mv = processHandlerException(request, response, handler, exception);//异常解析器
/* 1021 */ errorView = mv != null;
/* */ }
/* */ }
/* */
/* */
/* 1026 */ if ((mv != null) && (!mv.wasCleared())) {
/* 1027 */ render(mv, request, response);//喧染视图
/* 1028 */ if (errorView) {
/* 1029 */ WebUtils.clearErrorRequestAttributes(request);
/* */ }
/* */
/* */ }
/* */ protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response)
/* */ throws Exception
/* */ {
/* 1217 */ Locale locale = this.localeResolver.resolveLocale(request);
/* 1218 */ response.setLocale(locale);
/* */
/* */ View view;
/* 1221 */ if (mv.isReference())
/* */ {
/* 1223 */ View view = resolveViewName(mv.getViewName(), mv.getModelInternal(), locale, request);//视图解析器
/* 1224 */ if (view == null)
/* */ {
/* 1226 */ throw new ServletException("Could not resolve view with name '" + mv.getViewName() + "' in servlet with name '" + getServletName() + "'");
/* */ }
/* */ }
视图解析后通过在applicationcontext.xml中配置的视图解析器 进行了引用 然后将页面进行了转发,
rd.forward 就是进行了转发