Springboot工作原理

图解Springboot工作原理

在这里插入图片描述
SpringMVC执行流程:

  1. 用户发送请求,请求经过 SpringFramworkFilterChain,UserDefinedFilterChain、HttpServlet、SpringFrameworkServlet 至前端控制器 DispatcherServlet;
  2. DispatcherServlet 收到请求调用处理器映射器 HandlerMapping;
  3. HandlerMapping 根据请求 url 找到具体的处理器,生成处理器执行链 HandlerExecutionChain(包括处理器拦截器和处理器对象),返回给 DispatcherServlet;
  4. DispatcherServlet 根据处理器 Handler 获取处理器适配器 HandlerAdapter 并执行一系列的操作,如:参数封装,数据格式转换,数据验证等;
  5. 执行处理器 Handler(Controller,也叫页面控制器),执行完成返回 ModelAndView;
  6. HandlerAdapter 将 Handler 执行结果 ModelAndView 返回到 DispatcherServlet;
  7. DispatcherServlet 将 ModelAndView 传给视图解析器 ViewReslover,ViewReslover 解析后返回具体视图 View 给 DispatcherServlet;
  8. DispatcherServlet 对 View 进行渲染,将模型数据 model 填充至视图中。
  9. DispatcherServlet 返回 view,响应用户请求;
  10. 用户收到视图响应。

可以在Controller上打断点,跟踪Springboot的执行流程,如下图
在这里插入图片描述

Filter Interceptor ControllerAdvice Aspect And Controller

在这里插入图片描述

  1. 过滤器 Filter 是 java 过滤器,和框架无关,是所有过滤组件中最外层的,可以控制最初的http请求,粒度最大;
  2. 拦截器 Interceptor 是 Spring 框架的拦截器,可以拦截Controller外层的调用,可以控制请求的请求处理器和方法,但控制不了请求方法里的参数;
  3. ControllerAdvice 是controller的增强,和 ExceptionHandler 一起用来做全局统一异常处理,使用方式参考:《Springboot统一异常处理》
  4. 切面 Aspect,通过切面可以自定义要切入的类甚至再细的方法,粒度最小;
  5. Controller 请求处理器,和具体的业务逻辑相关。
Filter 和 Interceptor的区别
  1. Filter 是基于函数回调(doFilter()方法)的,而 Interceptor 则是基于 Java 反射的(AOP思想)。
  2. Filter 依赖于 Servlet 容器,而 Interceptor 不依赖于 Servlet 容器。
  3. Filter 对几乎所有的请求起作用,而 Interceptor 只能对 Handler 请求起作用。
  4. Interceptor 可以访问 Handler 的上下文,值栈里的对象,而Filter不能。
  5. 在 Handler 的生命周期里,Interceptor 可以被多次调用,而 Filter 只能在容器初始化时调用一次。
  6. Filter 只能对 request 和 response 进行操作,而 interceptor 可以对 request、response、handler、modelAndView、exception 进行操作。
Filter 和 Interceptor用法

过滤器(Filter)和拦截器(Interceptor)的代码示例,参见《Springboot Filter Interceptor》
在这里插入图片描述
Filter主要用法

  1. Filter主要用于对用户请求进行预处理,同时也可以进行通用逻辑判断,如响应时间统计、字符编解码,数据流转换、请求拦截等。
  2. Filter 依赖于 Servlet 容器,随Web应用一起启动,系统会自动调用 init(FilterConfig) 方法初始。
  3. Filter的 destroy() 方法,在Filter销毁时执行。
  4. Filter 的核心流程在 doFilter() 方法中定义,以chain.doFilter() 为分界线,Filter 链中 chain.doFilter() 前面的代码总是先执行,chain.doFilter() 后面的代码总是在最后执行,执行流程如下:
    在这里插入图片描述

在这里插入图片描述
Interceptor主要用法

  1. Interceptor 只针对 Controller 请求进行处理,拦截用户请求,如判断用户登录情况、权限验证等。
  2. Interceptor 通常通过三种方式定义,
    1)一种是对会话的拦截,实现 HandlerInterceptor 接口或继承 HandlerInterceptorAdapter,并注册到 MVC 的拦截队列中;
    2)另一种是实现WebRequestInterceptor接口,或继承WebRequestInterceptor接口的实现类来定义;
    3)第三种是对方法的拦截,需要使用@Aspect注解,在每次调用指定方法的前、后进行拦截。
  3. Interceptor主要方法用途
    1) preHandle() 在调用 Handler 之前进行拦截,其返回值表示是否中断后续操作,当其返回值为true时,表示继续向下执行;
    2)postHandle() 在控制器方法调用之后、视图渲染之前调用,可以通过此方法对请求域中的模型和视图做出进一步的修改;
    3)afterCompletion() 在会在视图渲染结束之后、返回响应之前执行,可以通过此方法实现一些资源清理、记录日志信息等工作。
    拦截器的执行流程如下:

在这里插入图片描述

Filter 和 Interceptor 执行时序

在这里插入图片描述

DispatcherServlet

前端控制器(DispatcherServlet),相当于 MVC 模式中的 C,是整个流程控制的中心,由它调用其它组件处理用户的请求。DispatcherServlet 的存在降低了组件之间的耦合性,提高了系统的可扩展性。

核心代码

/**
	 * Process the actual dispatching to the handler.
	 * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
	 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
	 * to find the first that supports the handler class.
	 * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
	 * themselves to decide which methods are acceptable.
	 * @param request current HTTP request
	 * @param response current HTTP response
	 * @throws Exception in case of any kind of processing failure
	 */
	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) {
					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 (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);
				}
			}
		}
	}

HandlerMapping

处理器映射器(HandlerMapping),负责根据用户请求的 url 找到 请求处理器(Handler),SpringMVC提供了不同的映射器来实现不同的映射方式,根据一定的规则去查找,例如:xml配置方式,接口方式,注解方式等。

Handler

请求处理器(Handler),是继 DispatcherServlet 的后端控制器,在 DispatcherServlet 的控制下 Handler 对具体的用户请求进行处理。由于 Handler 涉及到具体的用户业务请求,所以一般需要程序员根据业务需求开发Handler(Controller)。

HandlerAdapter

处理器适配器(HandlAdapter),负责调用请求处理器执行业务逻辑,通过扩展适配器可以执行更多类型的请求处理器,这是适配器模式的应用。

ModelAndView

ModelAndView 是 SpringMVC 的封装对象,它将 Model 和 View 封装在一起。

ViewResolver

视图解析器(ViewResolver),负责将处理结果生成 View 视图,视图解析器首先根据逻辑视图名解析成物理视图名,即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。

Model

模型数据(Model),是用于填充视图的数据模型,一般需要程序员根据业务需求开发。

View

视图(View),是springmvc的封装对象,是一个接口,SpringMVC 框架提供了很多的 View 视图类型,包括:jspview,pdfview, jstlView、freemarkerView、pdfView、ThemleafView 等。一般情况下需要通过页面标签或页面模版技术,将模型数据通过页面展示给用户,需要由程序员根据业务需求开发具体的页面。

参考文献
SpringMVC执行流程及工作原理
Spring中Filter和Interceptor的区别

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值