SpringMVC流程

一、重点方法:

类:DispatcherServlet
方法:
    protected void initStrategies(ApplicationContext context) {
        this.initMultipartResolver(context);
        this.initLocaleResolver(context);
        this.initThemeResolver(context);
        this.initHandlerMappings(context);
        this.initHandlerAdapters(context);
        this.initHandlerExceptionResolvers(context);
        this.initRequestToViewNameTranslator(context);
        this.initViewResolvers(context);
        this.initFlashMapManager(context);
    }
    protected void doDispatch(HttpServletRequest request){
    	...
    }

二、doDispatch() 解析

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
        HttpServletRequest processedRequest = request;
        HandlerExecutionChain mappedHandler = null;
        // 为true代表此请求是文件上传请求
        boolean multipartRequestParsed = false;
        // 给请求体设置异步属性的
        WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

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

                try {
                	// 判断是不是上传文件
                    processedRequest = this.checkMultipart(request);
                    multipartRequestParsed = processedRequest != request;
                    mappedHandler = this.getHandler(processedRequest);
                    if (mappedHandler == null) {
                        this.noHandlerFound(processedRequest, response);
                        return;
                    }

                    HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
                    String method = request.getMethod();
                    boolean isGet = HttpMethod.GET.matches(method);
                    if (isGet || HttpMethod.HEAD.matches(method)) {
                        long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
                        if ((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
                            return;
                        }
                    }
					// 处理链请求前执行一些前置方法
                    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
                        return;
                    }
					// ModelAndView  
                    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
                    if (asyncManager.isConcurrentHandlingStarted()) {
                        return;
                    }
					// view
                    this.applyDefaultViewName(processedRequest, mv);
                    mappedHandler.applyPostHandle(processedRequest, response, mv);
                } catch (Exception var20) {
                    dispatchException = var20;
                } catch (Throwable var21) {
                    dispatchException = new NestedServletException("Handler dispatch failed", var21);
                }

                this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
            } catch (Exception var22) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
            } catch (Throwable var23) {
                this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
            }

        } finally {
            if (asyncManager.isConcurrentHandlingStarted()) {
                if (mappedHandler != null) {
                    mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
                }
            } else if (multipartRequestParsed) {
                this.cleanupMultipart(processedRequest);
            }

        }
    }

1,WebAsyncUtils.getAsyncManager(request)

	/**
		请求体获取 WEB_ASYNC_MANAGER_ATTRIBUTE 属性
		为空则设置,虽然设置的是空的构造方法,但是有不少默认值
		如果想断点看看,可以用执行方法先后的请求体比较 Attribute
	*/
    public static WebAsyncManager getAsyncManager(ServletRequest servletRequest) {
        WebAsyncManager asyncManager = null;
        Object asyncManagerAttr = servletRequest.getAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE);
        if (asyncManagerAttr instanceof WebAsyncManager) {
            asyncManager = (WebAsyncManager)asyncManagerAttr;
        }

        if (asyncManager == null) {
            asyncManager = new WebAsyncManager();
            servletRequest.setAttribute(WEB_ASYNC_MANAGER_ATTRIBUTE, asyncManager);
        }

        return asyncManager;
    }
	/**
		gpt解析
		taskExecutor是一个java.util.concurrent.Executor类型
		的对象,用于执行异步处理任务
		concurrentResult和callableInterceptors分别用于保存
		并发结果和异步处理的拦截器
		deferredResultInterceptors用于保存
		DeferredResult异步处理的拦截器
	*/
    WebAsyncManager() {
        this.taskExecutor = DEFAULT_TASK_EXECUTOR;
        this.concurrentResult = RESULT_NONE;
        this.callableInterceptors = new LinkedHashMap();
        this.deferredResultInterceptors = new LinkedHashMap();
    }

三、this.checkMultipart(request);

    protected HttpServletRequest checkMultipart(HttpServletRequest request) throws MultipartException {
    	// isMultipart(request)断点进去看看怎么判断的
    	// 两个实现类,都打上断点就知道走哪个了
        if (this.multipartResolver != null && this.multipartResolver.isMultipart(request)) {
            if (WebUtils.getNativeRequest(request, MultipartHttpServletRequest.class) != null) {
                if (DispatcherType.REQUEST.equals(request.getDispatcherType())) {
                    this.logger.trace("Request already resolved to MultipartHttpServletRequest, e.g. by MultipartFilter");
                }
            } else if (this.hasMultipartException(request)) {
                this.logger.debug("Multipart resolution previously failed for current request - skipping re-resolution for undisturbed error rendering");
            } else {
                try {
                    return this.multipartResolver.resolveMultipart(request);
                } catch (MultipartException var3) {
                    if (request.getAttribute("javax.servlet.error.exception") == null) {
                        throw var3;
                    }
                }

                this.logger.debug("Multipart resolution failed for error dispatch", var3);
            }
        }

        return request;
    }
断点看,请求体没看到content-type啊
    public boolean isMultipart(HttpServletRequest request) {
        return StringUtils.startsWithIgnoreCase(request.getContentType(), this.strictServletCompliance ? "multipart/form-data" : "multipart/");
    }
request.getContentType()点进去看,断点走一圈
    public MessageBytes contentType() {
        if (this.contentTypeMB == null) {
            this.contentTypeMB = this.headers.getValue("content-type");
        }

        return this.contentTypeMB;
    }

四、HandleMapping --> getHandler --> HandlerExecutionChain

    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
    	// 此处看 this.initHandlerMappings(context);
        if (this.handlerMappings != null) {
            Iterator var2 = this.handlerMappings.iterator();

            while(var2.hasNext()) {
                HandlerMapping mapping = (HandlerMapping)var2.next();
                // handler包含interceptorList和handler接口
                // aop的拦截器mapping.getHandler(request)就是需要在此处加入,
                // MVC一个大组件 HandlerExecutionChain 
                HandlerExecutionChain handler = mapping.getHandler(request);
                if (handler != null) {
                    return handler;
                }
            }
        }

        return null;
    }
五种HandlerMapping

在这里插入图片描述
套娃严重,直接看结果
在这里插入图片描述

五、HandlerExecutionChain,Handler --> getHandlerAdapter --> HandlerAdapter

    protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
        if (this.handlerAdapters != null) {
            Iterator var2 = this.handlerAdapters.iterator();

            while(var2.hasNext()) {
                HandlerAdapter adapter = (HandlerAdapter)var2.next();
                // 选个实现类 SimpleControllerHandlerAdapter 看下就行
                // 看了此方法明了,处理成控制层可以处理的接口
                if (adapter.supports(handler)) {
                    return adapter;
                }
            }
        }

        throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
    }
SimpleControllerHandlerAdapter
    public boolean supports(Object handler) {
        return handler instanceof Controller;
    }

六、ModelAndView

HandlerAdapter --> AbstractHandlerMethodAdapter
protected ModelAndView invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
    ServletWebRequest webRequest = new ServletWebRequest(request, response);

    Object result;
    try {
		//获取数据绑定工厂
        WebDataBinderFactory binderFactory = this.getDataBinderFactory(handlerMethod); 
		//获取模型工厂
        ModelFactory modelFactory = this.getModelFactory(handlerMethod, binderFactory); 
		//创建可调用的处理方法
        ServletInvocableHandlerMethod invocableMethod = this.createInvocableHandlerMethod(handlerMethod); 
        if (this.argumentResolvers != null) {
			//设置参数解析器
            invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers); 
        }

        if (this.returnValueHandlers != null) {
			//设置返回值处理器
            invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers); 
        }
		//设置数据绑定工厂
        invocableMethod.setDataBinderFactory(binderFactory); 
		//设置参数名发现器
        invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer); 
		
		//创建视图模型容器
        ModelAndViewContainer mavContainer = new ModelAndViewContainer(); 
		//添加所有的FlashMap属性
        mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request)); 
        
		//初始化模型  -- 看下参数
		modelFactory.initModel(webRequest, mavContainer, invocableMethod); 
        
		//设置在重定向时是否忽略默认模型
		mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect); 
		
		//创建异步Web请求
        AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response); 
		//设置异步请求超时时间
        asyncWebRequest.setTimeout(this.asyncRequestTimeout); 
		//获取Web异步管理器
		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); 
		//设置任务执行器
        asyncManager.setTaskExecutor(this.taskExecutor); 
		//设置异步Web请求
        asyncManager.setAsyncWebRequest(asyncWebRequest); 
		//注册Callable拦截器
        asyncManager.registerCallableInterceptors(this.callableInterceptors); 
		//注册DeferredResult拦截器
        asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors); 
		
        //如果存在并发结果
		if (asyncManager.hasConcurrentResult()) { 
			//获取并发结果
            result = asyncManager.getConcurrentResult(); 
			//获取视图模型容器
            mavContainer = (ModelAndViewContainer)asyncManager.getConcurrentResultContext()[0]; 
			//清除并发结果
            asyncManager.clearConcurrentResult(); 
            LogFormatUtils.traceDebug(this.logger, (traceOn) -> {
                String formatted = LogFormatUtils.formatValue(result, !traceOn);
                return "Resume with async result [" + formatted + "]";
            });
			//包装并发结果
            invocableMethod = invocableMethod.wrapConcurrentResult(result); 
        }

		//调用处理方法
        invocableMethod.invokeAndHandle(webRequest, mavContainer, new Object[0]); 
		
		//如果没有并发处理启动
        if (!asyncManager.isConcurrentHandlingStarted()) { 
			//获取视图模型
            ModelAndView var15 = this.getModelAndView(mavContainer, modelFactory, webRequest); 
            return var15; //返回视图模型
        }

        result = null;
	} finally {
        webRequest.requestCompleted();
    }
	return (ModelAndView)result;
}

七、view

    private void processDispatchResult(HttpServletRequest request, HttpServletResponse response, @Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv, @Nullable Exception exception) throws Exception {
        boolean errorView = false;
        if (exception != null) {
            if (exception instanceof ModelAndViewDefiningException) {
                this.logger.debug("ModelAndViewDefiningException encountered", exception);
                mv = ((ModelAndViewDefiningException)exception).getModelAndView();
            } else {
                Object handler = mappedHandler != null ? mappedHandler.getHandler() : null;
                mv = this.processHandlerException(request, response, handler, exception);
                errorView = mv != null;
            }
        }

        if (mv != null && !mv.wasCleared()) {
        	// 点进去
            this.render(mv, request, response);
            if (errorView) {
                WebUtils.clearErrorRequestAttributes(request);
            }
        } else if (this.logger.isTraceEnabled()) {
            this.logger.trace("No view rendering, null ModelAndView returned.");
        }

        if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
            if (mappedHandler != null) {
                mappedHandler.triggerAfterCompletion(request, response, (Exception)null);
            }

        }
    }
/**
 * Render the given ModelAndView.
 * This is typically used to render a page with a template and model data.
 * This method will resolve the view name and create a view to render it.
 * If the ModelAndView contains a specific status code, it will set the response status accordingly.
 *
 * @param mv       the ModelAndView to render
 * @param request  current HTTP request
 * @param response current HTTP response
 * @throws Exception if view rendering or response handling fails
 */
protected void render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response) throws Exception {
    // 获取当前请求的区域
    Locale locale = this.localeResolver != null ? this.localeResolver.resolveLocale(request) : request.getLocale();
    response.setLocale(locale);
    // 获取视图名称
    String viewName = mv.getViewName();
    View view;
    if (viewName != null) {
        // 根据视图名称解析视图
        view = this.resolveViewName(viewName, mv.getModelInternal(), locale, request);
        if (view == null) {
            throw new ServletException("无法在名为 '" + this.getServletName() + "' 的servlet中解析视图名称为 '" + mv.getViewName() + "' 的视图");
        }
    } else {
        // 若视图名称为null,获取视图对象
        view = mv.getView();
        if (view == null) {
            throw new ServletException("ModelAndView [" + mv + "] 中既不包含视图名称,也不包含视图对象在名为 '" + this.getServletName() + "' 的servlet中");
        }
    }

    if (this.logger.isTraceEnabled()) {
        this.logger.trace("正在渲染视图 [" + view + "] ");
    }

    try {
        // 设置响应状态码
        if (mv.getStatus() != null) {
            request.setAttribute(View.RESPONSE_STATUS_ATTRIBUTE, mv.getStatus());
            response.setStatus(mv.getStatus().value());
        }
        // 渲染视图
        view.render(mv.getModelInternal(), request, response);
    } catch (Exception var8) {
        if (this.logger.isDebugEnabled()) {
            this.logger.debug("渲染视图 [" + view + "] 出错", var8);
        }
        throw var8;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
springMVC是一种基于MVC架构模式的Web框架,其流程如下: 1. 客户端发送请求到DispatcherServlet(前端控制器)。 2. DispatcherServlet根据请求信息调用HandlerMapping(处理器映射器)。 3. HandlerMapping根据请求URL找到对应的Handler(处理器)。 4. Handler执行业务逻辑并返回一个ModelAndView对象给DispatcherServlet。 5. DispatcherServlet根据返回的ModelAndView对象调用ViewResolver(视图解析器)。 6. ViewResolver解析ModelAndView中的View(视图)。 7. 最终将渲染后的视图返回给客户端。 以下是一个简单的示例代码: ```java // 定义Controller @Controller @RequestMapping("/hello") public class HelloController { @RequestMapping("/world") public ModelAndView helloWorld() { String message = "Hello World, Spring MVC!"; return new ModelAndView("hello", "message", message); } } // 定义视图解析器 @Bean public ViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver(); viewResolver.setPrefix("/WEB-INF/views/"); viewResolver.setSuffix(".jsp"); return viewResolver; } // 定义web.xml中的DispatcherServlet <servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>/WEB-INF/dispatcher-servlet.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> </servlet> // 定义dispatcher-servlet.xml中的HandlerMapping和ViewResolver <bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/views/"/> <property name="suffix" value=".jsp"/> </bean> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

码style

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值