Spring学习笔记(四)--MVC概述

1、 飞机web

最近马来西亚航空370号班机事故闹得沸沸扬扬,情节整的扑朔迷离,连我在钻研springMVC平和的心情都间接的受到了影响。正当我在想这个MVC的处理过程能够怎样获得更好的理解呢?灰机,灰机… 同事的议论和天上的嗡嗡声刹那间给了我一个答案,能够和民航系统进行类比。spring

民航系统相似于一个专业处理旅行的系统,此系统中有一些对旅行去作的事好比出差等自己意义不大,只在旅行系统中才存在的术语。好比说安全

1. 航班MH370是一个航班代号,表示从吉隆坡到北京的航班;session

2. 航班时刻表来进行记录,查找全部的飞行航班;mvc

3. 机票:在民航系统中惟一标识旅行者的token,上飞机须要飞机票,下飞机凭飞机票取行李;app

4. 安检:检查一下有没有带违禁品;工具

5. 飞机:完成从出发地到目的地的旅行;post

6. 机场:从乘客来看,无非是机票发售,安全检查,提供航班的地方。url

 

回到web系统,一个url就是惟一标识一个处理逻辑的名称。好比login.do就等于登录逻辑的标识。HandlerMapping至关于航班时刻表,标识航班和对应的路线。HandlerMethod至关于处理航班的飞机,来完成从登机处到目的地的转换。handlerAdapter 至关于从平常状态处和飞行状态转换的适配工具,相似于机场。HandlerInterceptor至关于在这个转换过程当中的共性处理逻辑,如购买机票,上飞机前要去凭身份证购买机票,到了目的地还要凭机票取行李等航班旅行通用的事项。spa

 

这四大组件构成了spring mvc 这个处理的基石。如图所示:

 

sidajingang

图1:四大组件

 

显然,当进行旅行,须要完成从普通状态到旅行状态的适配,如将身份证和钱转换成机票(在旅行中惟一标识本身身份的token) ,而后还要将行李存到飞机上;到了目的地机场后,就要进行旅行状态到普通状态的适配,使用机票进行取行李的操做。全部的登机过程都要经历一些通用逻辑的处理,如进行安检,进行行李托运/取回。这部分就构成了HandlerInterceptor的存在理由。

 

这四大组件充分的将web环境和业务逻辑环境解耦,使得业务逻辑能够更关注业务自己,并将横向的旅行逻辑和纵向的通用逻辑如安检进行切割。这四大组件自己都是可扩展的,HandlerMethod最通用,为方法级别的抽象。HandlerInteceptor是纵向逻辑的扩展接口,HandlerAdapter是从web环境到业务环境的适配扩展接口,HandlerMapping是将URL请求到业务逻辑映射的扩展接口。

 

1、 组件结构

HandlerMapping

Mapping

HanderAdapter

 

adapting

3、 处理过程:

  逻辑主要集中在org.springframework.web.servlet.DispatcherServlet.doDispatch(HttpServletRequest, HttpServletResponse)

 

A.根据请求(如url,参数,head等)特征来获得相应的方法和其匹配的拦截器集合。Spring mvc 3.0可用注解来标识处理逻辑方法和URL映射关系,所以涉及到扫描源代码标识为@Controller的类,并从中寻找@RequestMapping来进行映射表的生成。

mappedHandler = getHandler(processedRequest, false);

 

1. org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.getHandlerInternal(HttpServletRequest)

获取请求路径lookupPath去寻找相应的handlerMethod方法

 

  1.1 org.springframework.web.servlet.handler.AbstractHandlerMethodMapping.lookupHandlerMethod(String, HttpServletRequest)

 

     1.1.1 先将全部的映射按照requestURI来分组并存储在urlMap中。urlMap中根据请求路径找到对应的匹配列表,以进行进一步匹配。匹配列表中除请求的requestURI相同外,其余某些特征如方法,POST,GET,请求的head是不一样的。

 

     1.1.2 org.springframework.web.servlet.mvc.method.RequestMappingInfoHandlerMapping.getMatchingMapping(RequestMappingInfo, HttpServletRequest)

 

      先从请求中找到匹配条件,如method,params,produce,consume等条件,知足产生match

      并对这些match的匹配程度进行排序,获得最匹配的match

 

2.getHandlerExecutionChain(handler, request)

   将匹配的Interceptor也加入,并返回

 

B.HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

适配处理方法如何适配,会从request中获得相应的parameter,session,Model等等,来支持自定义Controller的参数。

1. org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(HttpServletRequest, HttpServletResponse, Object) 进行适配

 

1.1 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(HttpServletRequest, HttpServletResponse, HandlerMethod)

 

1.2 org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(HttpServletRequest, HttpServletResponse, HandlerMethod)

 

  1.2.1数据绑定方法和controller对应

  适配主要包含两部分,调用参数的适配和返回结果的适配

 

C.HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();

获得全部的interceptors而且将interceptors.preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)进行逐个调用。

 

D.进行调用

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

 

E.全部的interceptors进行postHandle调用

interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);

 

F.org.springframework.web.servlet.DispatcherServlet.render(ModelAndView, HttpServletRequest, HttpServletResponse)渲染页面

检查mv 是不是引用,好比是字符串,并进行相应view 的解析

 

1.org.springframework.web.servlet.DispatcherServlet.resolveViewName(String, Map<String, Object>, Locale, HttpServletRequest)调用viewResolver.resolveViewName(viewName,locale);

 

2. view.render(mv.getModelInternal(), request, response)

 

G.最后调用interceptor的org.springframework.web.servlet.HandlerInterceptor.afterCompletion(HttpServletRequest, HttpServletResponse, Object, Exception)

相关文章
相关标签/搜索