SpringMVC的执行流程

一、SpringMVC执行流程图

SpringMVC的执行流程_第1张图片

二、验证这个流程

1.准备工作

(1)准备thymeleaf来实现

因为我们没有去使用前后端分离,所以使用thymeleaf来渲染视图。先自定义一个controller,里面的方法作用就是设置视图和一个数据模型。

package com.csc.contorller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

@Controller
@RequestMapping("/user")
public class UserController {

    @RequestMapping("/info")
    public ModelAndView info(){
        ModelAndView mv = new ModelAndView();
        mv.setViewName("userInfo");
        mv.addObject("username","小明");
        return mv;
    }
}

 同时使用thymeleaf的语法,把对应的数据模型获取。




    
    Title


  

可以看见,浏览器输出的内容就是我们之前设置的数据模型。

SpringMVC的执行流程_第2张图片

(2)配置拦截器

自定义的拦截器。

package com.csc.interceptor;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * 自定义的拦截器
 */
@Component
public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        System.out.println("MyInterceptor...preHandle...执行了...");
        //true:放行  false:拦截
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
        System.out.println("MyInterceptor...postHandle...执行了...");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        System.out.println("MyInterceptor...afterCompletion...执行了...");
    }
}

还需要在配置类里面配置拦截器。

package com.csc.config;

import com.csc.interceptor.MyInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

/**
 * 配置类
 */
@Configuration
public class WebConfig implements WebMvcConfigurer {
    @Autowired
    private MyInterceptor myInterceptor;
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(myInterceptor);
    }
}

(3)配置全局异常处理器

自定义的异常处理器,为了方便展示效果,使用ModelAndView来返回进行视图的展示。

package com.csc.exception;

import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.servlet.ModelAndView;

/**
 * 自定义的全局异常处理器
 */
@ControllerAdvice
public class MyGlobalExceptionHandle {

    @ExceptionHandler({Exception.class}) //处理所有异常
    public ModelAndView handleException(Exception ex){
        ex.printStackTrace();
        ModelAndView mv = new ModelAndView();
        mv.setViewName("error");
        return mv;
    }
}

异常error.html。




    
    Title


    

服务器异常

服务器异常

服务器异常

服务器异常

至此,准备工作就已经完成。

2.debug看源码

(1)先搜索DispatcherServlet类

找到doDispatch()方法,这里面就是核心的SpringMVC的执行流程。SpringMVC的执行流程_第3张图片

(2)获取HandlerExecutionChain

1.先找到mappedHandler对象。SpringMVC的执行流程_第4张图片

2.步入进去发现,在循环迭代添加HandlerMapping对象。SpringMVC的执行流程_第5张图片

3.直接看handlerMappings对象,可以看见非常清楚,这几个就是我们自己写的contoller里面的路径,以及对应的方法,也是用Map储存的。SpringMVC的执行流程_第6张图片

4.步过,可以看mappedHandler对象的HandlerMethod有了对应的方法,以及还有自定义的拦截器,由此,HandlerExecutionChain对象就获取到了。SpringMVC的执行流程_第7张图片

(3)获取HandlerAdapter

1.找到对应的代码。SpringMVC的执行流程_第8张图片

2.步入进去,可以看见HandlerAdapter有许多处理适配器,其中就有熟悉的参数解析器和结果返回处理器。SpringMVC的执行流程_第9张图片

(4)执行拦截器的preHandle方法

1.这段代码就是应用preHandle。SpringMVC的执行流程_第10张图片

2.步入进去,就是循环把所有的拦截器的preHandle方法执行,直到返回值为false的时候停止。也可以看见控制台输出的内容就是自定义的拦截器的preHandle方法执行输出的内容。SpringMVC的执行流程_第11张图片

(5)执行HandlerAdapter(HandlerMethod)

1.找到对应的代码,因为ha就是前面获取的HandlerAdapter对象。SpringMVC的执行流程_第12张图片

2.在controller层打上断点,验证是否就是真正执行的该方法,发现就是在这。SpringMVC的执行流程_第13张图片

3.放行,回到刚刚的位置,可以发现mv就已经有了视图的数据模型。SpringMVC的执行流程_第14张图片

(6)执行拦截器的postHandle

1.可以看见该方法名字就是对应的执行拦截器的后置处理器。

2.步入,就是循环把所有的拦截器的后置处理器方法执行。SpringMVC的执行流程_第15张图片

(7)执行异常处理器逻辑(全局异常处理器)

1.该方法就是处理全局异常的方法。

2.处理异常的逻辑代码。SpringMVC的执行流程_第16张图片

3.如果有异常,就会执行自定义的异常处理方法,并返回对应的视图。SpringMVC的执行流程_第17张图片

(8)解析视图(使用response对象响应数据)

1.找到了render也就是渲染的意思。SpringMVC的执行流程_第18张图片

2.步入this.render(mv, request, response)进去。可以看见代码比较清晰,就是把mv里面的视图和数据模型通过视图解析器解析,然后通过response对象响应。SpringMVC的执行流程_第19张图片

(9)渲染视图

这个render方法里面的render方法就是真正渲染视图的方法。SpringMVC的执行流程_第20张图片

(10)执行拦截器的afterCompletion方法

1.这个mappedHandler.triggerAfterCompletion()就是执行拦截器afterCompletion方法。SpringMVC的执行流程_第21张图片

2.步入进去,这个方法就是执行所有拦截器的afterCompletion方法。SpringMVC的执行流程_第22张图片

3.面试应该如何说呢?

参考了黑马程序员的图片,如下图所示:

SpringMVC的执行流程_第23张图片

你可能感兴趣的:(java,mvc,面试)