springmvc执行流程简单(SpringMVC执行流程)
SpringMVC常用组件
DispatcherServlet:前端控制器 ,不需要工程师开发 ,由框架提供
作用:统一处理请求和响应 ,整个流程控制的中心 ,由它调用其它组件处理用户的请求 HandlerMapping:处理器映射器 ,不需要工程师开发 ,由框架提供作用:根据请求的url 、method等信息查找Handler ,即控制器方法
Handler:处理器 ,需要工程师开发
作用:在DispatcherServlet的控制下Handler对具体的用户请求进行处理HandlerAdapter:处理器适配器 ,不需要工程师开发 ,由框架提供
作用:通过HandlerAdapter对处理器(控制器方法)进行执行ViewResolver:视图解析器 ,不需要工程师开发 ,由框架提供
作用:进行视图解析,得到相应的视图 ,例如:ThymeleafView 、InternalResourceView 、 RedirectViewView:视图
作用:将模型数据通过页面展示给用户DispatcherServlet初始化过程
DispatcherServlet 本质上是一个 Servlet ,所以天然的遵循 Servlet 的生命周期 。所以宏观上是 Servlet生命周期来进行调度 。
初始化WebApplicationContext
所在类:org.springframework.web.servlet.FrameworkServle
protected WebApplicationContext initWebApplicationContext() { WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(getServletContext()); WebApplicationContext wac = null; if (this.webApplicationContext != null) { // A context instance was injected at construction time -> use it wac = this.webApplicationContext; if (wac instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext) wac; if (!cwac.isActive()) { // The context has not yet been refreshed -> provide services such as // setting the parent context, setting the application context id, etc if (cwac.getParent() == null) { // The context instance was injected without an explicit parent -> set // the root application context (if any; may be null) as the parent cwac.setParent(rootContext); } configureAndRefreshWebApplicationContext(cwac); } } } if (wac == null) { // No context instance was injected at construction time -> see if one // has been registered in the servlet context. If one exists, it is assumed // that the parent context (if any) has already been set and that the // user has performed any initialization such as setting the context id wac = findWebApplicationContext(); } if (wac == null) { // No context instance is defined for this servlet -> create a local one // 创建WebApplicationContext wac = createWebApplicationContext(rootContext); } if (!this.refreshEventReceived) { // Either the context is not a ConfigurableApplicationContext with refresh // support or the context injected at construction time had already been // refreshed -> trigger initial onRefresh manually here. synchronized (this.onRefreshMonitor) { // 刷新WebApplicationContext onRefresh(wac); } } if (this.publishContext) { // Publish the context as a servlet context attribute. // 将IOC容器在应用域共享 String attrName = getServletContextAttributeName(); getServletContext().setAttribute(attrName, wac); } return wac; }②创建WebApplicationContext
所在类:org.springframework.web.servlet.FrameworkServlet
protected WebApplicationContext createWebApplicationContext(@Nullable ApplicationContext parent) { Class<?> contextClass = getContextClass(); if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) { throw new ApplicationContextException( "Fatal initialization error in servlet with name " + getServletName() + ": custom WebApplicationContext class [" + contextClass.getName() + "] is not of type ConfigurableWebApplicationContext"); } // 通过反射创建 IOC 容器对象 ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(contextClass); wac.setEnvironment(getEnvironment()); // 设置父容器 wac.setParent(parent); String configLocation = getContextConfigLocation(); if (configLocation != null) { wac.setConfigLocation(configLocation); } configureAndRefreshWebApplicationContext(wac); return wac; }③DispatcherServlet初始化策略
FrameworkServlet创建WebApplicationContext后,刷新容器 ,调用onRefresh(wac) ,此方法在DispatcherServlet中进行了重写 ,调用了initStrategies(context)方法 ,初始化策略 ,即初始化
DispatcherServlet的各个组件
所在类:org.springframework.web.servlet.DispatcherServlet protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); initLocaleResolver(context); initThemeResolver(context); initHandlerMappings(context); initHandlerAdapters(context); initHandlerExceptionResolvers(context); initRequestToViewNameTranslator(context); initViewResolvers(context); initFlashMapManager(context); }SpringMVC的执行流程
用户向服务器发送请求 ,请求被SpringMVC 前端控制器 DispatcherServlet捕获 。
2) DispatcherServlet对请求URL进行解析 ,得到请求资源标识符(URI) ,判断请求URI对应的映射:
a) 不存在
i. 再判断是否配置了mvc:default-servlet-handler
ii. 如果没配置 ,则控制台报映射查找不到 ,客户端展示404错误iii. 如果有配置 ,则访问目标资源(一般为静态资源 ,如:JS,CSS,HTML),找不到客户端也会展示404错误
b) 存在则执行下面的流程
3) 根据该URI ,调用HandlerMapping获得该Handler配置的所有相关的对象(包括Handler对象以及Handler对象对应的拦截器) ,最后以HandlerExecutionChain执行链对象的形式返回 。
4) DispatcherServlet 根据获得的Handler,选择一个合适的HandlerAdapter 。
5) 如果成功获得HandlerAdapter ,此时将开始执行拦截器的preHandler(...)方法【正向】6) 提取Request中的模型数据 ,填充Handler入参 ,开始执行Handler(Controller)方法 ,处理请求 。在填充Handler的入参过程中 ,根据你的配置 ,Spring将帮你做一些额外的工作:
a) HttpMessageConveter: 将请求消息(如Json 、xml等数据)转换成一个对象 ,将对象转换为指定的响应信息b) 数据转换:对请求消息进行数据转换 。如String转换成Integer 、Double等
c) 数据格式化:对请求消息进行数据格式化 。 如将字符串转换成格式化数字或格式化日期等
d) 数据验证: 验证数据的有效性(长度 、格式等) ,验证结果存储到BindingResult或Error中
7) Handler执行完成后 ,向DispatcherServlet 返回一个ModelAndView对象 。8) 此时将开始执行拦截器的postHandle(...)方法【逆向】 。
9) 根据返回的ModelAndView(此时会判断是否存在异常:如果存在异常 ,则执行
HandlerExceptionResolver进行异常处理)选择一个适合的ViewResolver进行视图解析 ,根据Model
和View ,来渲染视图 。
10) 渲染视图完毕执行拦截器的afterCompletion(...)方法【逆向】 。
11) 将渲染结果返回给客户端。创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!