SpringMVC加载流程( 三 )


SpringMVC加载流程

文章插图
 
如上,DispatcherServlet继承自HttpServlet,并重写了doService方法,用于处理http请求,其中:
3.2.1. HttpServletBean 在HttpServlet的继承上增加了ConfigurableEnvironment属性,用于存放Servlet的配置项 。通过重写init方法,在初始化时将servlet配置项添加到上下文环境变量中,并在该方法中开放了initBeanWrapper和initServletBean方法给子类 。
3.2.2. FrameworkServlet 基于Servlet实现的Web框架,每个Servlet内部都对应一个XmlWebApplicationContext对象,且namespace格式为ServletName-servlet 。上面说了在没显示设定配置文件路径的情况下,且存在namespace时,会使用/WEB-INF/namespace.xml作为Spring配置文件,对应到demo即为/WEB-INF/dispatcher-servlet.xml 。FrameworkServlet重写了父类的intServletBean方法,对XmlWebApplicationContext的初始化工作 。Servlet在初始化XmlWebApplicationContext时,会尝试从ServletContext中获取根Context(上面提到的,会将根Ccontext放到ServletContext中以标记已经初始化过)并设置为当前Context的父Context,然后再按照雷士根Contextde 的初始化过程对其进行初始化 。不同的是,会在refresh前开放口子进行扩展,包括:
  • 对内通过重写子类的postProcessWebApplicationContext方法
  • 对外通过加载并执行globalInitializerClasses中配置的ApplicationContextInitializer类
FrameworkServlet还重写了父类的各doXXX方法,都交给processService方法,以处理Http请求 。processService最终委托给了doService方法 。
3.2.3. DispatchdrServlet 是SpringMVC处理Http请求的主要实现,主要完成了两件事:
3.1. 重写了onRefresh方法
 初始化时设置了众多默认处理策略,包括:文件处理策略、HandlerMapping处理策略、HandlerAdapter处理策略、HandlerException处理策略、View解析策略等 。SpringMVC在处理Http的每个步骤上,都提供了类似filter的机制,每个步骤都能够注册多个策略处理器,按照顺序选择出能够处理当前请求的策略并交给其处理 。而大部分的默认策略来至于spring-mvc模块下的org/springframework/web/servlet/DispatcherServlet.properties文件,如下:
SpringMVC加载流程

文章插图
 
下面为本人demo(SpringBoot)运行时DispatcherServlet各属性以及注册的各策略的情况
SpringMVC加载流程

文章插图
 
主要关注handlerMappings中的RequestMappingHandlerMapping和handlerAdapters中的RequestMappingHandlerAdapter 。这两个都不是在DispatcherServlet.properties文件中指定的,而是在开启 后自动注册的,这个后面会介绍 。
3.1.1 RequestMappingHandlerMapping初始化
 RequestMappingHandlerMapping主要用于查找@RequestMapping注解的handler,其继承关系如下:
SpringMVC加载流程

文章插图
 
  • AbstractHandlerMapping:实现了HandlerMapping接口,提供了获取handler的主要实现 。getHandler方法的实现为,将具体handler的查找委托给了子类的getHandlerInternal方法,然后跟当前请求路径相关的interceptor一起包装为一个HandlerExecutionChain返回 。interceptor为所有实现了MappedInterceptor接口的bean,会在AbstractHandlerMapping初始化的时候遍历上下文进行查找 。
  • AbstractHandlerMethodMapping:在AbstractHandlerMapping的基础上,主要提供了根据请求查找对应handler method的实现,即getHandlerInternal方法 。该类会在初始化时遍历上下文中所有的Bean,然后符合条件的Bean(通过isHandler方法),遍历当前Bean符合条件的方法(通过getMappingForMethod方法),每个方法都有一个对应的path,称为lookUpPath 。getHandlerInternal实现上也是通过请求的HttpServletRequest得到对应的lookUpPath,然后从内存缓存中获取对应的handler 。
  • RequestMappingHandlerMapping:@RequestMapping的实现,主要实现了 isHandler和getMappingForMethod 。isHandler:判断是否出现@Controller注解或者@RequestMapping注解 getMappingForMethod:根据@RequestMapping注解返回RequestMappingInfo实例 。
    3.1.2 RequestMappingHandlerAdapter初始化
  RequestMappingHandlerAdapter主要完成HandlerMethod的执行,,其继承关系如下:
SpringMVC加载流程

文章插图