zoukankan      html  css  js  c++  java
  • 浅析Spring MVC工作机制

    1.如何使用Spring MVC?

    • 在web.xml中配置一个DispatcherServlet
    • DispatchServlet初始化的时候会去寻找一个在应用程序的WEB-INF目录下的配置文件,命名规则是:servletName-servlet.xml  其中servletName是在部署描述符(web.xml)中Dispatcherservlet的名字。
    • 可以在所谓的配置文件中,扩展路径映射关系、定义视图解析器、定义业务逻辑处理流程规则。
    • 此外,也可以把Spring MVC的配置文件放在应用程序目录中的任何地方且名称任意,此时用servlet定义的init-param元素指定配置文件的位置与名字 如下所示
     1 <servlet>
     2         <servlet-name>springmvc</servlet-name>
     3         <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
     4         <init-param>
     5             <param-name>contextConfigLocation</param-name>
     6             <param-value>classpath:spring/springmvc-context.xml</param-value>
     7         </init-param>
     8         <load-on-startup>1</load-on-startup>
     9     </servlet>
    10     <servlet-mapping>
    11         <servlet-name>springmvc</servlet-name>
    12         <url-pattern>/</url-pattern>
    13     </servlet-mapping>

    2.SpringMVC如何工作?

    Spring MVC如何工作,主要看DispatcherServlet代码。

    在Servlet的init方法调用时DispatcherServlet执行Spring MVC的初始化工作。初始化工作在initStrategies中完成,code如下:

     1 protected void initStrategies(ApplicationContext context) {
     2         initMultipartResolver(context); //文件上传服务
     3         initLocaleResolver(context);//国际化问题
     4         initThemeResolver(context);//定义主题
     5         initHandlerMappings(context);//定义用户设置的请求映射关系
     6         initHandlerAdapters(context);//根据handler的类型定义不同的处理规则 ???
     7         initHandlerExceptionResolvers(context);//handler出错时使用
     8         initRequestToViewNameTranslator(context);//将指定的ViewName,加上前缀或者后缀
     9         initViewResolvers(context);//将View解析成页面
    10         initFlashMapManager(context);
    11     }

    HandlerMapping的初始化工作完成的两个最重要的工作就是将URL和 Handler的对应关系保存在handlerMap中,并将所有的interceptors对象保存在adaptedInterceptors数组中,等请求到来时执行所有的adaptedInterceptors数组中的interceptor对象。

    HandlerAdapter的初始化只是简单地创建一个HandlerAdapter对象,并将其保存在DispatcherServlet的handlerAdapters集合中。

    如果用户没有自定义HanlerDdapter的实现类,Spring MVC框架将提供默认的4个HandlerAdapter实现类。

    每次请求都会调用DispatcherServlet的doService->doDispatch 下面看一下这个方法的关键部分:

    // Determine handler for the current request.  
                    mappedHandler = getHandler(processedRequest);  
    .......
                // Determine handler adapter for the current request.  
                    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());  
    .......
              //Actually invoke the handler.
              try {  
                        mv = ha.handle(processedRequest, response, mappedHandler.getHandler());  
                    }  

    三个核心点:


    1.HandlerExecutionChain mappedHandler = getHandler(processedRequest);

    源码在此略过,主要就是遍历注册的HandlerMapping,调用他们的getHandler方法来找到对应的Handler。

    值得一提的是,Spring内部维护了一个Map<String,Object> handlerMap的数据结构, 用于存放 url和对应的handler,进而可以通过url找到handler。

    这里的处理链HandlerExecutionChain中包含用户定义的多个HandlerInterceptor对象,这些对象都有三个方法,preHandle postHandle分别在Handle执行前和执行后执行,afterCompletion在View渲染完成、DispatcherServlet返回之前执行。


    2.HandlerAdapter ha = getHandlerAdapter(mapperHandler.getHandler())

    为当前的Request寻找对应的HandlerAdapter,看哪个HandlerAdapter是支持这个handler的,如果找到了这个Adapter,那么调用它的handle方法


    3.ha.handle(processedRequest,response,mapperHandler.getHandler) 

    handle方法运用java反射机制执行handler的具体方法。

    这里真正的调用handle


    Ps:这里的源码有时间一定要深入研究下!

    Spring MVC框架中,有3个组件是用户必须要定义和扩展的:定义URL映射规则(@RequestMapping)、实现业务逻辑的Handler对象(UserController)、渲染模板资源(usr.ftl)

    其中HandlerMapping负责找到对应的handler(Controller)而HandlerAdapter负责找到要访问的函数。

    简单介绍一下程序运行的流程,访问指定url首先会由DispatcherServlet进行转发,再通过HandlerMapping找到对应的Handler,然后再拿找到的Handler和HandlerAdapter进行适配,之后就找到了想要执行的方法。

  • 相关阅读:
    我最早的个人网站
    阻止事件流冒泡
    阻止事件流冒泡
    我最早的个人网站
    复制到剪贴板
    复制到剪贴板
    js中的const
    oracle数据库查看修改字符集问题
    《一个程序员的奋斗史》帮我选封面哇! —— 猜封面页数赢赠书活动~
    linux内存管理概述
  • 原文地址:https://www.cnblogs.com/luyu1993/p/7132594.html
Copyright © 2011-2022 走看看