范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

SpringMVC核心组件HandlerMapping你清楚了吗?

  环境:Springboot2.4.11概述
  当一个请求过来后Spring是如何进行处理的?下面简单的罗列下请个的过程中核心组件
  SpringMVC处理的流程:DispatcherServlet 所有请求的入口HandlerMapping 将请求地址与处理程序关联HandlerAdapter 真正的处理程序,如执行上一步中对应的处理程序HandlerMethodArgumentResolver 对参数进行解析,这里面还涉及到很多其它东西HanlderMethodReturnValueHandler 对返回值进行输出处理ViewResolver 当上一步返回结果为ModelAndView时会应用视图解析器
  一个请求的处理过程获取HandlerMapping
  该步从容器中获取所有的HandlerMapping对象。public class DispatcherServlet extends FrameworkServlet {   private List handlerMappings;   private void initHandlerMappings(ApplicationContext context) {     // 在ApplicationContext中查找所有HandlerMappings,包括祖先上下文。     Map matchingBeans = BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);     if (!matchingBeans.isEmpty()) {       this.handlerMappings = new ArrayList<>(matchingBeans.values());       AnnotationAwareOrderComparator.sort(this.handlerMappings);     }   } }查找HandlerMapping
  该步从获取的HandlerMapping中查找适合当前请求的HandlerMapping。public class DispatcherServlet extends FrameworkServlet {   private List handlerMappings;   protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {     HandlerExecutionChain mappedHandler = null;     // 查找能够处理当前请求HandlerMapping对象,主要就是根据请求的URI     mappedHandler = getHandler(processedRequest);   }   protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {     if (this.handlerMappings != null) {       // HandlerMapping 实现了Ordered接口,是由顺序的,那在这里,谁先匹配谁就处理       for (HandlerMapping mapping : this.handlerMappings) {        // 在这个过程中会通过查找到的HandlerMapping对象,然后获取合适的处理程序(可能是个Bean对象或是HandlerMethod对象等)         HandlerExecutionChain handler = mapping.getHandler(request);         if (handler != null) {           return handler;         }       }     }     return null;   } }
  系统默认有如下5个HandlerMappingRequestMappingHandlerMappingBeanNameUrlHandlerMappingRouterFunctionMappingSimpleUrlHandlerMappingWelcomePageHandlerMapping
  一般默认都是RequestMappingHandlerMapping匹配
  接下来看看是如何进行匹配的
  调用父类AbstractHandlerMapping#getHandler方法,父类中的这个方法中定义了特定的逻辑,而针对每种不同的HandlerMapping实现是需要具体的子类来实现AbstractHandlerMapping#getHandlerInternal方法public abstract class AbstractHandlerMapping {   public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {     Object handler = getHandlerInternal(request);     // ...     HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);     // ...     return executionChain; 	}    } public abstract class AbstractHandlerMethodMapping {   protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {     // 获取请求地址     String lookupPath = initLookupPath(request);     try {       // 根据请求地址查询对应的HandlerMethod       HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);       return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);     }     // ...   }   protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {     List matches = new ArrayList<>();     // 在已注册的Mapping中根据请求的url进行查找     // 这样查找的this.pathLookup.get(urlPath);     List directPathMatches = this.mappingRegistry.getMappingsByDirectPath(lookupPath);     if (!matches.isEmpty()) {       Match bestMatch = matches.get(0);       // ...       handleMatch(bestMatch.mapping, lookupPath, request);       return bestMatch.getHandlerMethod();     }     // ...   } }
  到这里就是查找处理请求的HandlerMethod对象。接下来看看系统是如何进行初始化所有的HandlerMethod初始化HandlerMethodpublic class RequestMappingHandlerMapping {   public void afterPropertiesSet() {     // ...     super.afterPropertiesSet();   } } public abstract class AbstractHandlerMethodMapping {   public void afterPropertiesSet() {     initHandlerMethods();   }   protected void initHandlerMethods() {     // getCandidateBeanNames获取容器中的所有Bean 		for (String beanName : getCandidateBeanNames()) {       if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX)) {         processCandidateBean(beanName);       }     }     handlerMethodsInitialized(getHandlerMethods());   }   protected void processCandidateBean(String beanName) {     Class<?> beanType = null;     try {       // 根据BeanName获取对应的Class       beanType = obtainApplicationContext().getType(beanName);     }     // ...     // isHandler方法判断当前的类是否符合条件,该方法在RequestMappingHandlerMapping中实现     // isHandler方法用处就是判断当前的Class@Controller或者@RequestMapping注解     // 这样就将所有的@Controller与RequestMappingHandlerMapping关联一起了。     if (beanType != null && isHandler(beanType)) {       // 查找所有的HandlerMethod       detectHandlerMethods(beanName);     }   }   protected void detectHandlerMethods(Object handler) {     Class<?> handlerType = (handler instanceof String ? obtainApplicationContext().getType((String) handler) : handler.getClass());     if (handlerType != null) {       Class<?> userType = ClassUtils.getUserClass(handlerType);       // 查找Class中的所有方法       Map methods = MethodIntrospector.selectMethods(userType, (MethodIntrospector.MetadataLookup) method -> {         try {           // 将每一个符合条件的方法(方法上有@RequestMapping注解的)           // 封装到RequestMappingInfo对象中           return getMappingForMethod(method, userType);         }         // ...       });       methods.forEach((method, mapping) -> {         Method invocableMethod = AopUtils.selectInvocableMethod(method, userType);         // 将找到的所有Method进行注册添加到Map中         registerHandlerMethod(handler, invocableMethod, mapping);       });     }   }   protected void registerHandlerMethod(Object handler, Method method, T mapping) {     this.mappingRegistry.register(mapping, handler, method);   }   class MappingRegistry {     // T  : RequestMappingInfo, handler: 字符串(usersController)Bean名称,method:请求方法对象     public void register(T mapping, Object handler, Method method) {       // 创建HandlerMethod对象       HandlerMethod handlerMethod = createHandlerMethod(handler, method);       // ...       for (String path : directPaths) {         // 缓存上,在请求到来的时候 会从这个pathLookup集合中查找         this.pathLookup.add(path, mapping);       }     }   } }
  完毕!!!
  求个关注+转发
  公众:Springboot实战案例锦集
  spring data jpa 高级应用
  Spring MVC 异常处理方式
  Spring事务实现原理源码分析
  Spring 自定义Advisor以编程的方式实现AOP
  SpringBoot项目中应用Spring Batch批处理框架,处理大数据新方案
  Spring IOC容器对Bean实例化的过程详解源码分析
  Spring Boot Security防重登录及在线总数
  Spring Security记住我功能实现及源码分析
  Spring Security 自定义登录成功后的逻辑

承认吧!元气森林的广撒网娱乐营销就是人傻钱多品牌观察02作者小藕编辑阿笔新消费赛道中,跑在最前面的几个,永远是最早抓住细分品类机会的那几个。以在饱受争议中逐渐被人们习惯的0糖气泡水为例元气森林的崛起,走的并非饮料行业常规操作。2016年接盘辱华品牌的艺人都有谁?杨幂刘雯解约,他们转眼就接手大家还记得前段时间的国外品牌HM耐克等牌子抵制新疆棉花导致一众国内明星与其解约。事情也是过去了一段时间了,风平浪静以后,就有人开始钻空子了。当初解约的明星付了很多违约金,一转眼就有华为绝不妥协!Mate50系列被多方确认,麒麟芯片5G一个都不少在国内手机市场,iPhone13系列之所以力压群雄销量火热,许多分析人士认为,根本原因就是缺少华为的制衡。当智能手机进入5G时代,华为凭借着前期大量的投入和自身在5G领域半导体领域电视剧仙剑奇侠传4要来了仙剑奇侠传4电视剧仙剑4终于有消息了,已筹备有4年之久的仙剑4预计在2022年2月开机。仙剑4其实在2016年的时候就已经正式的备案了,但是四年多的时间并没有正式开机的消息传出,直加密兔正式下线!小米不干了中国基金报记者忆山近日,运营了近四年的小米区块链游戏加密兔宣布即将正式下线。2021年NFT元宇宙概念曾一度爆火,在国内也带火了不少游戏概念公司,而在国外备受追捧的区块链游戏,在国寻宝埃及埃及艳后的珠宝花园今天我们带着大家来到非洲人口第二大国,可能大家看标题也猜到了吧,今天的主角就是世界四大文明古国金字塔的故乡埃及!埃及金字塔埃及,国土略呈不规则的四方形,地处欧亚非之洲的交通要冲,北运用到极致的搭配手法渐变与对比FromAltuzarra本场秀运用了轻快明亮的艳色调搭配轻浅色系作为辅邻近色的黄与橙对比色的蓝与黄深浅不同的红色与晴空蓝的撞色,色彩上整体活泼趣味搭配上常用的手法是西装衬衫背心西NASA发现一颗小行星,估值高达50亿美元,将于2060年实施开采?地球茫茫宇宙中,只是一粒沙子,而人类自己,也许只是沙子上的细菌但放眼宇宙,比地球小的天体还比比皆是,比如月球,比如火星,再比如那些数量未知,经常给地球带来威胁的小行星们。据科学界统我们根据全世界点击榜单,总结了2021年最热门的主机类游戏文晓生讲个鬼故事,2021年只剩下17天了。年初做的计划完成了吗?立的flag拔掉了吗?许的愿望实现了吗?幼稚,这年头谁还认真做计划啊,新冠变种最后的形态都还没进化出来,能好好活着神秘的香巴拉,只有拥有纯净心的人才能进入走进香巴拉视频链接httpswww。ixigua。com7024830634740843022?logTag099da744702076f69f73雪域高原上,在美丽的吉雪卧塘,人拳皇97那些非主流高手玩家们相信广大拳皇97拳迷应该注意到无论高手或或是刚入坑的小白,对战主力基本都是那几个强势角色八神神乐大猪玛丽草薙大门之流,这些强势人物角色对战比赛看久了免不了有审美疲劳之感。大蛇c位妥
好消息,中国女排前队长朱婷,回归赛场时间定,蔡斌这下放心了最近中国女排可以说是喜事连连。七月底知名的女排运动员张常宁和丈夫吴冠希举行了盛大的婚礼。期间,不少排坛的运动员和名人都出席。恩师郎平更是不远万里从美国飞回来,虽然后来因为各种安排没全红婵家富裕了!房子装修完成,妈妈翘二郎腿惬意,爸爸吃鸵鸟蛋在过去一年时间里,夏季奥运会和冬季奥运会先后顺利完成,其中有两位体育运动员爆红,一位就是跳水天才全红婵,另一位则是滑雪天才谷爱凌,两位都是我国的骄傲,取得同样辉煌的成就,而二人的成约书亚机会来了!美国邹市明约书亚可以复仇,但必须减掉肌肉8月20日,前两度世界重量级拳王约书亚将面临职业生涯最严峻的考验,届时他将与乌西克拳王乌西克展开二番战,双方曾在去年9月有过一番战,当时乌西克以一致的点数获胜,而这场二番战已经让约郭艾伦最大的悲剧,就是被辽篮抛弃的时候,连招呼都不会打郭艾伦最大的悲剧,就是被辽篮抛弃的时候,连招呼都不会打。网友热议一针见血地指出这就是格局,就为站什么位置发火吗?也许这张海报是有心栽花,也许是无心挿柳。这样反而起到炒作的作用,现在美国女排深夜做出决定!中国女排蔡斌收坏消息,袁心玥李盈莹麻烦了北京时间7月31日深夜,美国媒体曝光了美国女排的最新计划,他们表示为了能够备战世锦赛,美国女排将会在8月下旬与土耳其女排进行热身赛,作为中国女排的竞争对手,美国女排和土耳其女排约热国乒男单大获全胜!30零封对手,击败过张本智和,何卓佳开门红北京时间8月2日,国际乒联突尼斯挑战赛正在进行。正在进行的是单项资格赛,双打方面,国乒4对组合需要参加资格赛。目前,国乒双打大获全胜。女双选手何卓佳石洵瑶直落三局,总比分30零封东潜力很大!美媒评分卫TOP25布克米切尔前2,火箭核心无缘前10当年科比卡特艾弗森和麦迪4大分卫的时代早已过去很久了,如今的NBA里最好的得分后卫是谁呢?美媒Hoopshype的专家们也评出了新赛季NBA联盟里的25大得分后卫。当年号称第一分卫过分!杜兰特已经不想和詹姆斯做对比,只因詹皇未来无法夺冠杜兰特在联盟中一向将詹姆斯作为竞争对手,他很多行为都是在步詹姆斯的后尘,不过根据美国媒体最新消息爆料,正处于交易流言中心的杜兰特已经不想将自己拿来和詹姆斯作对比,只因詹姆斯未来已经村妇别瞎演!把赵丽颖秦海璐和刘琳放一块看,高下立判在暑假档的电视剧里,最受关注,最火爆的就当属赵丽颖,刘威,罗晋等人主演的幸福到万家了。该剧的许多情节引发了观众的共鸣,所以,观众也随着剧情的发展发表了一系列言论,在微博热搜中,相关镜头前风姿绰约,真人个个黯然失色,这5位女星全都是上镜脸前面聊到不上镜脸,是以陈妍希李小冉为代表的皮相美人。而与之对应的上镜脸则多是骨相优过皮相,现实生活里的她们远不及镜头前风姿绰约,甚至黯然失色,这些演员统称电影脸。最经典的莫过于周迅新赛季CBA10月10日开赛新华社北京8月1日电中国男篮职业联赛(CBA)官网1日发布公告称,20222023赛季CBA联赛将于2022年10月10日开赛,原计划今年3月举行的2022年CBA全明星周末将于2