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

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 自定义登录成功后的逻辑

常见的5个买车知识误区,内容过于真实,可能你也犯过对于普通用户来说,对汽车知识存在误区其实有很多很多,小木能力有限,只是列举了几个比较常见的误区,也不能算是科普,没那么高端,只是把自己知道的一点小知识分享给大家,当大家再次遇到这个家庭影院如何吸音?实用声学分享!新手小白学起来防止被坑俗话说三分器材,七分环境。要想获得好的音响效果,必须要有好的环境。如果房间的声学条件很差,再好再昂贵的设备也是无济于事。关于别墅地下室家庭影院,我们要达到哪些条件才算是一个好的声学为什么近几年来家庭影院越来越受欢迎?家庭影院市场及现状!根据一份专业的家庭影院行业研究报告(20192025年中国家庭影院行业发展深度调研与未来趋势分析报告)中显示未来几年,中国家庭影院市场仍会稳步增长。数字化技术的看了这3款新上市的电动汽车,我直接退掉了特斯拉的订单要说现在汽车圈最火热的话题,那非新能源汽车莫属。作为新能源汽车领域最大的一条干支电动汽车,无疑是各个车企未来主攻的方向。相比早期电动汽车的高昂价位虚标技术落后等缺点,如今倒显得更有买激光电视会踩雷吗?激光电视和液晶电视有什么区别呢?小白必看我看不少朋友在争论液晶电视和激光电视的优缺点,其实大可不必。无论是液晶电视还是激光电视,每一种产品都有各自的优势,也有某方面的不足,但是都有各自的用户群体。这是因为每个人具体的需求linux之lscpu命令lscpu命令显示有关CPU架构的信息lscpu命令安装bashlscpucommandnotfoundUbuntuaptgetinstallutillinuxCentOSyumilinux之pkill命令可以按照进程名杀死进程,pkill命令可以按照进程名杀死进程。pkill和killall应用方法差不多,也是直接杀死运行中的程序如果您想杀掉单个进程,请用kill来杀掉。命令语法p从首批用户实拍看一加9系列影像实力,行业第一梯队稳了从预热阶段开始,影像就是一加9系列的重要卖点。尤其是刘作虎力争影像第一的宣言放出以后,人们对于一加9系列的影像表现就充满期待或者质疑。一加9系列尤其是一加9Pro,到底能不能当得起果粉换到一加9Pro这系统流畅稳定不卡顿,和iOS一样好用笔者是一个重度手机使用者,也算是一名果粉。从iPhone4开始直到iPhone12,笔者用过的苹果手机不下六部。iPhone手机的iOS系统A系列芯片影像系统等等,一度让我对And买车多花50万,买到的是什么?10万与60万的车究竟差在哪?本质上,车就是交通工具,10万或者60万都是人赋予它的定义。比如沙发的定义是坐着休息的,床的定义是躺着睡觉的,反过来也并非不可以。人为什么要赋予不同的定义呢?小木觉得更多的还是精神100万的豪车怎么买划算?学会这一招,实际花费不到10万相信每个喜欢汽车的人心中都有一个豪车梦,但不是每个人都有买豪车的实力,或者说不是每个人都愿意花100万来买车。对于普通家庭来说,用100万来买车的确不太划算。不过如果是混迹生意场的
2021北京软件和信息技术服务综合实力企业(二十七)北京和利时系统工程有限公司发布日期20220308来源北京软件和信息服务业协会企业简介和利时公司始创于1993年,是中国领先的自动化与信息技术解决方案供应商。业务聚焦于工业自动化交通自动化医疗大健康。公司提2天后发布,iPhoneSE3更多信息曝光,国行价格或超预期手机圈在经历了短暂的平淡期之后,马上就要迎来一个新的大爆发。那就是两天后苹果的春节发布会。要说春季发布会以往并不会引起太大的轰动,主要是带来一些Pad,耳机,电脑之类的产品,国内用卢伟冰问哪款手机续航最强,iPhone13系列高票当选,其实大错特错卢伟冰询问哪款手机续航最强,网友推荐iPhone13ProMax,继K50电竞版发布后,本月K50宇宙其它型号也即将登场亮相。而在发布前夕,Redmi产品经理卢伟冰也与网友就手机各2月新能源销量同比增1803月8日,乘用车市场信息联席会发布2022年2月乘用车市场数据及分析。2月,全国乘用车市场零售达到124。6万辆,同比增长4。2,环比下降40。02月新能源乘用车零售销量达到27。2022年值得考虑的4款手机,几乎没有差评,你打算怎么选?很多朋友都问我,2022年都有哪些手机是可以方向入手,没有差评的?其实现在市面上的好机型真的非常多,要选出几款好用的手机,真的不算太难。今天,就带大家一起看看,值得我们考虑的4款好小米集团W获南向资金连续3天净买入小米集团W获南向资金连续3天净买入,累计净买入金额10。75亿港元,股价累计下跌12。09。证券时报数据宝统计显示,3月8日港股通(包括沪市港股通及深市港股通)成交活跃股合计成交1估值或超500亿美元外媒英特尔自动驾驶部门秘密申请IPO中新经纬3月8日电据路透中文网报道,英特尔自动驾驶汽车部门Mobileye周一在美国秘密申请首次公开发行(IPO),有望跻身今年最大规模的股票上市交易之列。报道称,Mobileye红杉押注的AI公司第四范式再度冲刺IPO竞品公司上市一月市值腰斩科创板日报(记者敖瑾)讯,又一家AI公司冲刺港股IPO。近日,人工智能软件公司第四范式再次向港交所递交上市申请,向港股IPO发起二次冲刺。进入2022年以来,已有多家人工智能企业挂Inteli712700HRTX3050Ti,6699元的雷神911MT值得入手吗?一英特尔第12代酷睿处理器正式铺货,雷神911MT2022款全方位升级随着数码圈的年度盛会CES2022的顺利召开,处理器行业巨头的英特尔陆陆续续补齐了第12代酷睿处理器家族,其中武极电脑日报速递24年来第一次!IntelNVIDIAAMD同时发显卡要闻24年来第一次!IntelNVIDIAAMD同时发显卡1998年,Inteli740在独立显卡市场上昙花一现,此后就一直是NVIDIAAMD(ATI)双雄的天下。24年过去了,中国芯片真正的龙头3大芯片企业,主力净流入过亿芯片主要指的就是集成电路,一个小小的芯片里面可能涵盖了很多个电路,这些电路都利用了一些手段进行压缩。一个正常的电路一般为一米,而芯片电路为一毫米或者一厘米,芯片都不只单单一个电路,