快捷搜索:  汽车  科技

springmvc执行流程(一张图教你看懂Spring)

springmvc执行流程(一张图教你看懂Spring)protected void onRefresh(ApplicationContext context) { this.initStrategies(context); } protected void initStrategies(ApplicationContext context) { //初始化文件的解析 this.initMultipartResolver(context); //本地初始化 this.initLocaleResolver(context); //主题解析 this.initThemeResolver(context); //处理器映射 this.initHandlerMappings(context);

前言

今天主要给大家分享的是关于Spring MVC的知识内容,刚好是最近用到的知识点,所以今天就来给大家安利安利了!

那么,老规矩,话不多说!上干货.....

springmvc执行流程(一张图教你看懂Spring)(1)

DispatcherServlet的设计

springmvc执行流程(一张图教你看懂Spring)(2)

DispatcherServlet的父类是FrameworkServlet,FrameworkServlet的父类则是HttpServletBean。HttpServletBean继承了Web容器所提供的HttpServlet,所以它可以载入Web容器中的Servlet。

DispatcherServlet的工作大致可以分为两个部分:一个是初始化部分,由initServletBean()启动,通过initWebApplicationContext()方法最终调用DispatcherServlet的initStrategies方法。在这个方法里,DispatcherServlet对MVC模块的其他部分进行了初始化,比如handlerMapping,ViewResolver等。另一个是对HTTP请求进行相应,作为一个servlet,web容器会调用doGet() doPost()方法,在经过FrameworkServlet的processRequest简单处理后,会调用DispatcherServlet的doService()方法,在这个方法中封装了doDispatch(),这个doDispatch()是Dispatcher实现MVC模式的主要部分。

下边我们来看源码:

DispatcherServlet的初始化

public final void init() throws ServletException { if (this.logger.isDebugEnabled()) { this.logger.debug("Initializing servlet '" this.getServletName() "'"); } //根据参数初始化bean的属性 try { PropertyValues pvs = new HttpServletBean.ServletConfigPropertyValues(this.getServletConfig() this.requiredProperties); BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this); ResourceLoader resourceLoader = new ServletContextResourceLoader(this.getServletContext()); bw.registerCustomEditor(Resource.class new ResourceEditor(resourceLoader this.getEnvironment())); this.initBeanWrapper(bw); bw.setPropertyValues(pvs true); } catch (BeansException var4) { this.logger.error("Failed to set bean properties on servlet '" this.getServletName() "'" var4); throw var4; } //调用子类的initServletBean进行具体的初始化 this.initServletBean(); if (this.logger.isDebugEnabled()) { this.logger.debug("Servlet '" this.getServletName() "' configured successfully"); } }

FrameworkServlet的initServletBean方法

protected final void initServletBean() throws ServletException { this.getServletContext().log("Initializing Spring FrameworkServlet '" this.getServletName() "'"); if (this.logger.isInfoEnabled()) { this.logger.info("FrameworkServlet '" this.getServletName() "': initialization started"); } long startTime = System.currentTimeMillis(); try { //初始化Spring Ioc容器 this.webApplicationContext = this.initWebApplicationContext(); this.initFrameworkServlet(); } catch (ServletException var5) { this.logger.error("Context initialization failed" var5); throw var5; } catch (RuntimeException var6) { this.logger.error("Context initialization failed" var6); throw var6; } if (this.logger.isInfoEnabled()) { long elapsedTime = System.currentTimeMillis() - startTime; this.logger.info("FrameworkServlet '" this.getServletName() "': initialization completed in " elapsedTime " ms"); } } protected WebApplicationContext initWebApplicationContext() { WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext()); WebApplicationContext wac = null; //判断是否已经被初始化 if (this.webApplicationContext != null) { //如果Web Ioc容器在启动的时候创建,那么就沿用它 wac = this.webApplicationContext; if (wac instanceof ConfigurableWebApplicationContext) { ConfigurableWebApplicationContext cwac = (ConfigurableWebApplicationContext)wac; if (!cwac.isActive()) { //如果父容器为空的情况 if (cwac.getParent() == null) { cwac.setParent(rootContext); } //如果Spring Ioc容器还没有刷新,那么就进行刷新父容器上下文设置id等操作 this.configureAndRefreshWebApplicationContext(cwac); } } } //没有初始化,则查找是否有存在的Spring Web Ioc容器 if (wac == null) { wac = this.findWebApplicationContext(); } //没有初始化,也没有找到,则自己创建一个 if (wac == null) { wac = this.createWebApplicationContext(rootContext); } //当onRefresh还没调用过,执行onRefresh方法 if (!this.refreshEventReceived) { this.onRefresh(wac); } if (this.publishContext) { //作为Servlet上下文属性发布到IOC容器 String attrName = this.getServletContextAttributeName(); this.getServletContext().setAttribute(attrName wac); if (this.logger.isDebugEnabled()) { this.logger.debug("Published WebApplicationContext of servlet '" this.getServletName() "' as ServletContext attribute with name [" attrName "]"); } } return wac; }

//创建 protected WebApplicationContext createWebApplicationContext(ApplicationContext parent) { Class<?> contextClass = this.getContextClass(); if (this.logger.isDebugEnabled()) { this.logger.debug("Servlet with name '" this.getServletName() "' will try to create custom WebApplicationContext context of class '" contextClass.getName() "'" " using parent context [" parent "]"); } if (!ConfigurableWebApplicationContext.class.isAssignableFrom(contextClass)) { throw new ApplicationContextException("Fatal initialization error in servlet with name '" this.getServletName() "': custom WebApplicationContext class [" contextClass.getName() "] is not of type ConfigurableWebApplicationContext"); } else { //初始化MVC ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext)BeanUtils.instantiateClass(contextClass); wac.setEnvironment(this.getEnvironment()); wac.setParent(parent); wac.setConfigLocation(this.getContextConfigLocation()); this.configureAndRefreshWebApplicationContext(wac); return wac; } }

上边代码展示了对Spring Ioc容器的初始化,除了SpringMVC上下文创建外,还需要启动SpringMVC的其他一些配置初始化,通过onRefresh调用来完成。这个方法就在DispatcherServlet当中,实际调用的initStrategies进行配置

protected void onRefresh(ApplicationContext context) { this.initStrategies(context); } protected void initStrategies(ApplicationContext context) { //初始化文件的解析 this.initMultipartResolver(context); //本地初始化 this.initLocaleResolver(context); //主题解析 this.initThemeResolver(context); //处理器映射 this.initHandlerMappings(context); //处理器适配器 this.initHandlerAdapters(context); //handler的异常处理解析器 this.initHandlerExceptionResolvers(context); //当处理器没有返回逻辑视图名等相关信息,自动将请求URL映射为路基视图名 this.initRequestToViewNameTranslator(context); //视图解析器 this.initViewResolvers(context); //flash this.initFlashMapManager(context); }

Spring MVC的核心组件

  • MultipartResolver:文件解析器,用于支持服务器的文件上传
  • LocaleResolver:国际化解析器,可以提供国际化的功能
  • ThemeResolver:主题解析器,类似于软件皮肤的转换功能
  • HandlerMappings:处理器映射器,它会包装用户提供一个控制器的方法和它的一些拦截器
  • HandlerAdapters:处理器适配器,因为处理器会在不同的上下文运行,所以Spring MVC会找到合适的适配器,然后运行处理器服务方法
  • HandlerExceptionResolvers:处理器异常解析器,处理器有可能产生异常,如果产生异常,则通过异常解析器来处理它
  • RequestToViewNameTranslator:视图逻辑名称转换器,在控制器中返回一个视图的名称,通过它可以找到实际的视图。当处理器没有返回逻辑视图名等相关信息时,自动请求URL映射为逻辑视图名
  • ViewResolvers:视图解析器,当控制器返回后,通过视图解析器会把逻辑视图名称进行解析,然后定位实际视图

Spring MVC流程

springmvc执行流程(一张图教你看懂Spring)(3)

  1. 用户发送请求至前端控制器DispatcherServlet
  2. DispatcherServlet收到请求调用HandlerMapping处理器映射器
  3. 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet
  4. DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
  5. 执行处理器(Controller,也叫后端控制器)
  6. Controller执行完成返回ModelAndView
  7. HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
  8. DispatcherServlet将ModelAndView传给ViewReslover视图解析器
  9. ViewReslover解析后返回具体View
  10. DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)
  11. DispatcherServlet响应用户

DispatcherServlet有接收请求,响应结果,转发等作用。有了DispatcherServlet之后,可以减少组件之间的耦合度

猜您喜欢: