文章末尾有Spring+外置Tomcat / SpringBoot+内置Tomcat 从启动到接口请求的详细全流程图
tomcat调用Spring-service概要过程:
ApplicationFilterChain.doFilter
-> 执行tomcat过滤器doFilter之前的逻辑
-> 执行过滤器doFilter,当前方法压栈
->已执行最后一个过滤器,执行servlet.service(request, response);【此处servlet是DispatcherServlet】
->执行DispatcherServlet.doDispatch方法
1.检查是否multi文件请求(上传下载)
2.根据请求相对路径,查询符合的mappedHandler映射处理器【一共有几种:RequestMappingHandlerMapping、BeanNameUrlHandlerMapping、RouterFunctionMapping】,包装映射处理器到HandlerExecutionChain。
3.根据mappedHandler找到HandlerAdapter
4.通过HandlerExecutionChain遍历执行拦截器HandlerInterceptor实现类方法preHandler【如果拦截器preHandle返回false,【则请求直接结束】并【倒序遍历拦截器的方法afterCompletion】
5.获得当前handler对应的HandlerAdapter对象
6.通过HandlerAdapter调用接口方法
7.遍历执行拦截器HandlerInterceptor实现类方法postHandler
8.处理异常,执行异常对应的执行器,如果有视图则渲染View
9.倒序遍历拦截器的方法afterCompletion
->【spring-mvc容器发布事件】ServletRequestHandledEvent【事件信息包含request、response关键信息】
-> 执行过滤器doFilter之后的逻辑,当前方法出栈
-> 【结束】
tomcat 可以向其中注册自定义过滤器
1.实现抽象过滤类:GenericFilter
2.注册过滤器Bean对象
3.tomcat启动过程 StandardContext 会进行注册过滤器
注册tomcat自定义过滤器代码如下:
@Component
public class WebRequestFilterConduction extends GenericFilterBean {
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse httpServletResponse = (HttpServletResponse) servletResponse;
System.out.println("WebRequestFilterConduction - before");
filterChain.doFilter(servletRequest, httpServletResponse);
System.out.println("WebRequestFilterConduction - after");
}
}
tomcat请求执行的责任链模式的过滤器的核心逻辑:
封装过滤链核心类:ApplicationFilterChain 【封装了很多Filter】
调用doFilter方法【主要记录当前执行到哪个过滤器,调用下一个过滤器,以及执行完所有过滤器后,进行调用service接口的逻辑】
springMvc 可以向其中注册自定义过滤器
注册springMvc自定义过滤器代码如下:
@Component
public class MvcFilterConductionConfigure implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new MvcFilterConduction()).addPathPatterns("/**");
}
}
@Component
public class MvcFilterConduction implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("MvcFilterConduction - preHandle before");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("MvcFilterConduction - postHandle before");
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
System.out.println("MvcFilterConduction - postHandle after");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("MvcFilterConduction - afterCompletion before");
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
System.out.println("MvcFilterConduction - afterCompletion after");
}
}
SpringMvc-九大组件
// 初始化 MultipartResolver:主要用来处理文件上传.如果定义过当前类型的bean对象,那么直接获取,如果没有的话,可以为null
initMultipartResolver(context);
// 初始化 LocaleResolver:主要用来处理国际化配置,基于URL参数的配置(AcceptHeaderLocaleResolver),基于session的配置(SessionLocaleResolver),基于cookie的配置(CookieLocaleResolver)
initLocaleResolver(context);
// 初始化 ThemeResolver:主要用来设置主题Theme
initThemeResolver(context);
// 初始化 HandlerMapping:映射器,用来将对应的request跟controller进行对应
initHandlerMappings(context);
// 初始化 HandlerAdapter:处理适配器,主要包含Http请求处理器适配器,简单控制器处理器适配器,注解方法处理器适配器
initHandlerAdapters(context);
// 初始化 HandlerExceptionResolver:基于HandlerExceptionResolver接口的异常处理
initHandlerExceptionResolvers(context);
// 初始化 RequestToViewNameTranslator:当controller处理器方法没有返回一个View对象或逻辑视图名称,并且在该方法中没有直接往response的输出流里面写数据的时候,spring将会采用约定好的方式提供一个逻辑视图名称
initRequestToViewNameTranslator(context);
// 初始化 ViewResolver: 将ModelAndView选择合适的视图进行渲染的处理器
initViewResolvers(context);
// 初始化 FlashMapManager: 提供请求存储属性,可供其他请求使用
initFlashMapManager(context);
SpringMvc-九大组件-默认加载的实现类
从此配置文件加载的DispatcherServlet.properties【spring-webmvc包】
org.springframework.web.servlet.LocaleResolver=org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolver
org.springframework.web.servlet.ThemeResolver=org.springframework.web.servlet.theme.FixedThemeResolver
org.springframework.web.servlet.HandlerMapping=org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\
org.springframework.web.servlet.function.support.RouterFunctionMapping
org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
org.springframework.web.servlet.function.support.HandlerFunctionAdapter
org.springframework.web.servlet.HandlerExceptionResolver=org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\
org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\
org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolver
org.springframework.web.servlet.RequestToViewNameTranslator=org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator
org.springframework.web.servlet.ViewResolver=org.springframework.web.servlet.view.InternalResourceViewResolver
org.springframework.web.servlet.FlashMapManager=org.springframework.web.servlet.support.SessionFlashMapManager