当前位置:首页 > 科技  > 软件

详解SpringMVC底层原理

来源: 责编: 时间:2024-01-08 09:17:25 323观看
导读作者 | 波哥审校 | 重楼笔者的专业是软件技术,主修Java,记得刚开始写Web应用的时候,都是直接写Servlet,有多少个请求服务就写多少个Servlet,于是一个系统中出现了一堆的Servlet,记得那会JSP也很流行,后来又经历了Struts1、St

作者 | 波哥5Gl28资讯网——每日最新资讯28at.com

审校 | 重楼5Gl28资讯网——每日最新资讯28at.com

笔者的专业是软件技术,主修Java,记得刚开始写Web应用的时候,都是直接写Servlet,有多少个请求服务就写多少个Servlet,于是一个系统中出现了一堆的Servlet,记得那会JSP也很流行,后来又经历了Struts1、Struts2,到现在前后端技术分离了,则更多是用SpringMVC。5Gl28资讯网——每日最新资讯28at.com

随着技术的发展,你会发现写代码变得越来越简单,当然这个简单是建立在前辈大神们深邃的设计思想上的,今天我们就来详细聊聊SpringMVC,学习SpringMVC底层原理的同时,感受下大神们的设计思想。5Gl28资讯网——每日最新资讯28at.com

我们先来通过一张图了解下SpringMVC处理请求的整体流程:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

使用过SpringMVC的老铁们都知道,在SpringMVC中最核心的就是DispatcherServlet类,接下来笔者将从DispatcherServlet如何处理请求的整体流程来阐述它的底层实现。5Gl28资讯网——每日最新资讯28at.com

DispatcherServlet毫无疑问是一个HttpServlet,因此可以追踪到所有的请求都会进入到doDispatch方法中,而这个方法就是咱们要解剖的方法:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

该方法主要有几条主线:获取HandlerExecutionChain、获取HandlerAdapter、调用Adapter的handle方法、视图处理器处理。下面我们将从这几个主线逐一分析。5Gl28资讯网——每日最新资讯28at.com

一、获取HandlerExecutionChain

首先说明下这个HandlerExecutionChain,它里面封装了一堆的Interceptor拦截器,以及Handler,它是一个处理链,通过getHandler方法获取得到:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

从代码中我看到,这里循环handlerMappings,调用HandlerMapping的getHandler方法来获取HandlerExecutionChain对象,获取到了就返回,那这个handlerMappings都包含了哪些HandlerMapping呢?它们是什么时候被塞到handlerMappings集合中去的?5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

在DispatcherServlet的initStrategies方法中,会初始化一堆的数据,其中就有调用initHandlerMappings方法来初始化HandlerMapping,放到handlerMappings集合中,至于initStrategies方法是怎么被调用的,大家看下DispatcherServlet的继承结构图,然后根据Servlet的生命周期跟踪下相信就知道了。5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

我们来看下initHandlerMappings方法:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

从方法中可以看出,从Spring的Bean工厂中获取HandlerMapping.class类型的Bean,以得到handlerMappings,在实际过程中,和咱们实际应用相关的HandlerMapping主要包括:BeanNameUrlHandlerMapping、SimpleUrlHandlerMapping、
RequestMappingHandlerMapping这三类,当然还有其他。5Gl28资讯网——每日最新资讯28at.com

所以我们就知道了,上面是调用这三个HandlerMapping的getHandler方法来获取HandlerExecutionChain对象。我们大概猜想,这个getHandler方法是根据请求的URL路径,来获取到处理的对象或者方法,这个是顺理成章的,因为我们在开发的时候,就是通过配置path路径来明确请求的路径和方法或类的对应关系的。5Gl28资讯网——每日最新资讯28at.com

我们先来看它们内部到底存放了什么,以及getHandler方法的具体逻辑,我们主要看BeanNameUrlHandlerMapping和
RequestMappingHandlerMapping。5Gl28资讯网——每日最新资讯28at.com

1.BeanNameUrlHandlerMapping

5Gl28资讯网——每日最新资讯28at.com

从它的继承关系图中可以看到,它是Aware的实现类,跟踪它的生命周期,Spring会调用initApplicationContext方法,然后调用detectHandlers方法来找到对应的Handler,并调用registerHandler方法将找到的Handler添加到handlerMap这个Map集合中去。5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

那上面"对应的Handler"需要满足什么条件呢?5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

看上面的判断逻辑,表明如果bean的名称是以"/"开头,则满足条件,然后从Spring的Bean工厂中获取到对应的Bean实例,添加到handlerMap集合。5Gl28资讯网——每日最新资讯28at.com

在具体使用时,可以实现Controller和HttpRequestHandler接口,同时Component注解的value值以"/"开头。5Gl28资讯网——每日最新资讯28at.com

好,数据准备完成,接下来就是getHandler方法:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

跟踪代码可以看出,就是根据URL从handlerMap获取到对应的实例,随后再将handler和HandlerInterceptor封装成HandlerExecutionChain对象:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

2.RequestMappingHandlerMapping

5Gl28资讯网——每日最新资讯28at.com

RequestMappingHandlerMapping是InitializingBean的实现类,在bean的初始化阶段,它的afterPropertiesSet方法会被Spring调用,跟踪该方法:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

发现获取所有的bean实例,然后循环调用processCandidateBean方法:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

必须满足一定条件的实例才会被处理,这个条件就是类上面包含Controller或者RequestMapping注解:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

对于满足上述条件的bean,会在detectHandlerMethods方法中将RequestMapping注解中的路径和对应的方法封装成HandlerMethod,并添加到mappingLookup集合中。5Gl28资讯网——每日最新资讯28at.com

然后调用getHandler方法,根据请求URL从mappingLookup集合中取出HandlerMethod,并封装成HandlerExecutionChain对象。5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

二、获取HandlerAdapter

在上述调用getHandler方法,获取到HandlerExecutionChain对象后,接下来调用getHandlerAdapter方法获取HandlerAdapter:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

循环所有的HandlerAdapter,调用supports方法判断HandlerAdapter是否支持处理Handler。这里有两个问题:第一、HandlerAdapter有哪些?它们是什么时候被初始化的?第二、每个HandlerAdapter的supports方法的具体实现;5Gl28资讯网——每日最新资讯28at.com

1.HandlerAdapter有哪些?它们是什么时候被添加到handlerAdapters的?

同上,HandlerAdapter的初始化也是在initStrategies方法中发起的,在initHandlerAdapters方法中完成具体的添加:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

可以看到,从Spring容器中获取所有的HandlerAdapter类型的Bean添加到handlerAdapters中,默认情况下包括:
RequestMappingHandlerAdapter、HandlerFunctionAdapter、HttpRequestHandlerAdapter、SimpleControllerHandlerAdapter四个实现类的Bean实例。5Gl28资讯网——每日最新资讯28at.com

2.HandlerAdapter的supports方法的具体实现

我们这里主要讲下
RequestMappingHandlerAdapter、SimpleControllerHandlerAdapter和HttpRequestHandlerAdapter的supports实现逻辑:5Gl28资讯网——每日最新资讯28at.com

  • RequestMappingHandlerAdapter

5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

Handler是HandlerMethod类型,则由RequestMappingHandlerAdapter处理。5Gl28资讯网——每日最新资讯28at.com

  • SimpleControllerHandlerAdapter

5Gl28资讯网——每日最新资讯28at.com

如果handler是Controller的实现类,则会由SimpleControllerHandlerAdapter处理。5Gl28资讯网——每日最新资讯28at.com

  • HttpRequestHandlerAdapter

如果handler是HttpRequestHandler的实现类,则会由HttpRequestHandlerAdapter处理。5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

三、调用HandlerAdapter的handle方法

在获取到HandlerAdapter后,还会调用interceptor的preHandle方法,这里就不详细描述了。这里咱们直接看HandlerAdapter的handle方法的具体实现。5Gl28资讯网——每日最新资讯28at.com

1.RequestMappingHandlerAdapter

相对于其他Adapter的处理方法,RequestMappingHandlerAdapter要复杂的的多5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

显示创建ServletInvocableHandlerMethod对象,然后往对象中添加HandlerMethodArgumentResolvers和HandlerMethodReturnValueHandlers,这两个接口很重要,是SpringMVC的两个重要扩展点。5Gl28资讯网——每日最新资讯28at.com

随后开始处理,总结来说主要做了两件事:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

获取方法参数值,然后调用方法:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

执行方法相对简单,咱们主要来看看是如何获取方法参数值的:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

先获取到方法上的所有参数信息MethodParameter,然后调用
resolvers.supportsParameter方法来判断是否支持对参数类型进行转换,那这个resolvers是啥?它是一个HandlerMethodArgumentResolver,里面包含了一堆的HandlerMethodArgumentResolver,而这个HandlerMethodArgumentResolver就是专门负责参数转换用的:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

除了SpringMVC自己提供的HandlerMethodArgumentResolver外,还支持让咱们自己来提供,只要实现HandlerMethodArgumentResolver即可。SpringMVC通过调用HandlerMethodArgumentResolver类的supportsParameter方法来找到一个适合处理的HandlerMethodArgumentResolver,找到了合适的Resolver后,调用它的resolveArgument方法来进行参数转换,最终得到所有的参数值。5Gl28资讯网——每日最新资讯28at.com

对返回值进行处理

在调用方法完成后,如果有返回值,则调用returnValueHandlers.handleReturnValue来处理返回值,这个returnValueHandlers是HandlerMethodReturnValueHandler类型的实例,它包含了一堆的HandlerMethodReturnValueHandler,HandlerMethodReturnValueHandler就是专门处理返回值的实现类,除了默认的HandlerMethodReturnValueHandler外,SpringMVC还允许咱们自己实现HandlerMethodReturnValueHandler。5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

首先SpringMVC会获取一个最合适的HandlerMethodReturnValueHandler:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

选择的逻辑就是循环调用所有HandlerMethodReturnValueHandler的supportsReturnType方法,返回为true的就是最合适的:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

得到HandlerMethodReturnValueHandler后,调用它的handleReturnValue方法来完成返回值的处理。5Gl28资讯网——每日最新资讯28at.com

2.SimpleControllerHandlerAdapter

5Gl28资讯网——每日最新资讯28at.com


SimpleControllerHandlerAdapter的handle方法,就是执行Controller实现类的handleRequest方法。5Gl28资讯网——每日最新资讯28at.com

3.HttpRequestHandlerAdapter

5Gl28资讯网——每日最新资讯28at.com

HttpRequestHandlerAdapter的handle方法,就是执行HttpRequestHandler实现类的handleRequest方法。5Gl28资讯网——每日最新资讯28at.com

四、视图渲染

上述完成Adapter的handle方法后,会执行过滤器HandlerInterceptor的postHandle方法,这里不再描述。如果返回值是ModelAndView,则会调用processDispatchResult,来完成视图渲染:5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

这里会先得到一个View,也就是视图器,然后调用view的render方法来完成渲染处理。那核心点就是如何获取这个View。5Gl28资讯网——每日最新资讯28at.com

5Gl28资讯网——每日最新资讯28at.com

循环调用viewResolvers中ViewResolver的resolveViewName方法,得到最合适的View。默认情况下SpringMVC提供了四种类型的View:BeanNameViewResolver、ViewResolverComposite、
InternalResourceViewResolver、ContentNegotiatingViewResolver,当然咱们也可以自己实现ViewResolver,从而添加自己的View。5Gl28资讯网——每日最新资讯28at.com

以上就是SpringMVC底层的大致实现原理,希望能给读者朋友们一些帮助!5Gl28资讯网——每日最新资讯28at.com

作者介绍

波哥,互联行业从业10余年,先后担任项目总监及架构师。目前专攻技术,喜欢研究技术原理。技术全面,主攻Java,精通JVM底层机制及Spring全家桶底层框架原理,熟练掌握当前主流的中间件、服务网格等技术原理。5Gl28资讯网——每日最新资讯28at.com


5Gl28资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-57910-0.html详解SpringMVC底层原理

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 九条微服务最佳实践,你学会了哪条?

下一篇: 理解 Node.js 中的事件循环

标签:
  • 热门焦点
  • 一年经验在二线城市面试后端的经验分享

    忠告这篇文章只适合2年内工作经验、甚至没有工作经验的朋友阅读。如果你是2年以上工作经验,请果断划走,对你没啥帮助~主人公这篇文章内容来自 「升职加薪」星球星友 的投稿,坐
  • 量化指标是与非:挽救被量化指标扼杀的技术团队

    作者 | 刘新翠整理 | 徐杰承本文整理自快狗打车技术总监刘新翠在WOT2023大会上的主题分享,更多精彩内容及现场PPT,请关注51CTO技术栈公众号,发消息【WOT2023PPT】即可直接领取
  • 中国家电海外掘金正当时|出海专题

    作者|吴南南编辑|胡展嘉运营|陈佳慧出品|零态LT(ID:LingTai_LT)2023年,出海市场战况空前,中国创业者在海外纷纷摩拳擦掌,以期能够把中国的商业模式、创业理念、战略打法输出海外,他们依
  • 10天营收超1亿美元,《星铁》比《原神》差在哪?

    来源:伯虎财经作者:陈平安即便你没玩过《原神》,你一定听说过的它的大名。恨它的人把《原神》开服那天称作是中国游戏史上最黑暗的一天,有粉丝因为索尼在PS平台上线《原神》,怒而
  • “又被陈思诚骗了”

    作者|张思齐 出品|众面(ID:ZhongMian_ZM)如今的国产悬疑电影,成了陈思诚的天下。最近大爆电影《消失的她》票房突破30亿断层夺魁暑期档,陈思诚再度风头无两。你可以说陈思诚的
  • 网红炒股不为了赚钱,那就是耍流氓!

    来源:首席商业评论6月26日高调宣布入市,网络名嘴大v胡锡进居然进军了股市。在一次财经媒体峰会上,几个财经圈媒体大佬就“胡锡进炒股是否知道认真报道”展开讨论。有
  • 认真聊聊东方甄选:如何告别低垂的果实

    来源:山核桃作者:财经无忌爆火一年后,俞敏洪和他的东方甄选依旧是颇受外界关心的“网红”。7月5日至9日,为期5天的东方甄选“甘肃行”首次在自有App内直播,
  • 8月见!小米MIX Fold 3获得3C认证:支持67W快充

    这段时间以来,包括三星、一加、荣耀等等有不少品牌旗下的最新折叠屏旗舰都得到了不少爆料,而小米新一代折叠屏旗舰——小米MIX Fold 3此前也屡屡被传
  • 世界人工智能大会国际日开幕式活动在世博展览馆开启

    30日上午,世界人工智能大会国际日开幕式活动在世博展览馆开启,聚集国际城市代表、重量级院士专家、国际创新企业代表,共同打造人工智能交流平台。上海市副市
Top