Spring MVC @RequestMapping

Spring MVC:@RequestMapping Spring MVC @RequestMapping注解介绍 阅读详情

http://www.iocoder.cn/Spring-MVC/carlzhao/RequestMapping/

要想了解决Spring MVC是怎么把@RequestMapping注解了的方法以及类解析的,首先我们需要关注AbstractHandlerMethodMapping#afterPropertiesSet这个方法,而这个方法是Spring的init方法,是Spring在进行初始化bean之前在DI注入之后调用到的方法。所以当Spring容器初始化之后,@RequestMapping就会被解析成Spring容器的bean管理。通过这个方法的说明也能验证之前所说的。我们首先来关注一下@RequestMapping的时序图:
这里写图片描述

下面就入口方法。

/**
 * Detects handler methods at initialization.
 */
public void afterPropertiesSet() {
    initHandlerMethods();
}

1、初始化处理client页面request的方法

下面我们就要重点关注AbstractHandlerMethodMapping#initHandlerMethods这个方法了。

/**
 * Scan beans in the ApplicationContext, detect and register handler methods.
 * @see #isHandler(Class)
 * @see #getMappingForMethod(Method, Class)
 * @see #handlerMethodsInitialized(Map)
 */
protected void initHandlerMethods() {
    if (logger.isDebugEnabled()) {
        logger.debug("Looking for request mappings in application context: " + getApplicationContext());
    }

    // 读取Spring容器中的所有beanNames
    String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
            BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
            getApplicationContext().getBeanNamesForType(Object.class));

    // 遍历这些bean,检测出处理方法
    for (String beanName : beanNames) {
        // 判断这个bean是不是处理类(根据这个类是否使用了@Controller或@RequestMapping)
        if (isHandler(getApplicationContext().getType(beanName))){
            detectHandlerMethods(beanName);
        }
    }
    // 处理方法后期处理,Spring空实现,方便以后扩展
    handlerMethodsInitialized(getHandlerMethods());
}

那么我们的关注点就需要放在detectHandlerMethods这个方法上了。

2、detectHandlerMethods

下面我们再来看一下AbstractHandlerMethodMapping#detectHandlerMethods这个方法。

protected void detectHandlerMethods(final Object handler) {
    // 从Spring容器中获取这个类
    Class<?> handlerType =
            (handler instanceof String ? getApplicationContext().getType((String) handler) : handler.getClass());

    // Avoid repeated calls to getMappingForMethod which would rebuild RequestMatchingInfo instances
    final Map<Method, T> mappings = new IdentityHashMap<Method, T>();
    final Class<?> userType = ClassUtils.getUserClass(handlerType);

    // 从处理类(@Controller)中获取处理方法(@RequestMapping)
    Set<Method> methods = HandlerMethodSelector.selectMethods(userType, new MethodFilter() {
        public boolean matches(Method method) {
            T mapping = getMappingForMethod(method, userType);
            if (mapping != null) {
                mappings.put(method, mapping);
                return true;
            }
            else {
                return false;
            }
        }
    });
    // 注册方法,
    for (Method method : methods) {
        registerHandlerMethod(handler, method, mappings.get(method));
    }
}

3、getMappingForMethod

Spring MVC通过RequestMappingHandlerMapping#getMappingForMethod(Method method, Class

/**
 * Uses method and type-level @{@link RequestMapping} annotations to create
 * the RequestMappingInfo.
 * @return the created RequestMappingInfo, or {@code null} if the method
 * does not have a {@code @RequestMapping} annotation.
 * @see #getCustomMethodCondition(Method)
 * @see #getCustomTypeCondition(Class)
 */
@Override
protected RequestMappingInfo getMappingForMethod(Method method, Class<?> handlerType) {
    RequestMappingInfo info = null;
    // 这个方法是否使用@RequestMapping信息
    RequestMapping methodAnnotation = AnnotationUtils.findAnnotation(method, RequestMapping.class);
    if (methodAnnotation != null) {
        // 空实现,方便以后扩展
        RequestCondition<?> methodCondition = getCustomMethodCondition(method);
        // 创建RequestMappingInfo比较简单,如果感兴趣可以自己去看看
        info = createRequestMappingInfo(methodAnnotation, methodCondition);
        // 查询这个Controller上面使用@RequestMapping信息
        RequestMapping typeAnnotation = AnnotationUtils.findAnnotation(handlerType, RequestMapping.class);
        if (typeAnnotation != null) {
            // 空实现,方便以后扩展
            RequestCondition<?> typeCondition = getCustomTypeCondition(handlerType);
            // 把Class上面的@RequestMapping信息与方法上的@RequestMapping信息合并起来
            info = createRequestMappingInfo(typeAnnotation, typeCondition).combine(info);
        }
    }

    return info;
}

返回info主要是包含@RequestMapping的标签信息,我们可以看看info中的信息:
这里写图片描述

4、registerHandlerMethod

然后我们就关注一下。第二步中的detectHandlerMethods方法中的registerHandlerMethod方法。

/**
 * Register a handler method and its unique mapping.
 * @param handler the bean name of the handler or the handler instance
 * @param method the method to register
 * @param mapping the mapping conditions associated with the handler method
 * @throws IllegalStateException if another method was already registered
 * under the same mapping
 */
protected void registerHandlerMethod(Object handler, Method method, T mapping) {
    HandlerMethod newHandlerMethod = createHandlerMethod(handler, method);
    HandlerMethod oldHandlerMethod = this.handlerMethods.get(mapping);
    if (oldHandlerMethod != null && !oldHandlerMethod.equals(newHandlerMethod)) {
        throw new IllegalStateException("Ambiguous mapping found. Cannot map '" + newHandlerMethod.getBean() +
                "' bean method \n" + newHandlerMethod + "\nto " + mapping + ": There is already '" +
                oldHandlerMethod.getBean() + "' bean method\n" + oldHandlerMethod + " mapped.");
    }

    // 防止定义相同的处理映射
    this.handlerMethods.put(mapping, newHandlerMethod);
    if (logger.isInfoEnabled()) {
        logger.info("Mapped \"" + mapping + "\" onto " + newHandlerMethod);
    }

    Set<String> patterns = getMappingPathPatterns(mapping);
    // 存在URL与RequestMappingInfo的映射
    for (String pattern : patterns) {
        if (!getPathMatcher().isPattern(pattern)) {
            this.urlMap.add(pattern, mapping);
        }
    }
}

现在我们来看看这个解析之后这个类之中属性。
这里写图片描述
我们主要把关注点停留到urlMap与handlerMethods上。
1、urlMap
这里写图片描述
我们可以看到urlMap属性中保存的是请求路径与RequestMappingInfo的映射信息。
2、handerMethods
这里写图片描述
我们可以看到handerMethods属性中保存的是RequestMappingInfo与HanderMethod的映射。HanderMethod主要保存这个类与处理请求具体的方法。

当页面有url请求过来.首先通过urlMap查询RequestMappingInfo的信息,然后再通过handerMethods查询到HanderMethod的信息。这样url请求是不是与Controller中的方法结合了起来。具体是怎么调用的,可以看看我写的Blog – Spring MVC DispatcherServlet

Spring MVC框架下的@RequestMapping映射实践 在Spring框架中,类级别上的注解提供了一种将一个特定的类映射到URL路径上的方法。该注解可以被放置在控制器类的上方,目的是为控制器类中的所有方法提供一个共同的基础URL。这种方式可以简化URL的配置,并保持一致性。// 方法逻辑// 方法逻辑以上代码中,定义了一个基础路径/api/v1,所有在这个控制器中定义的方法都将继承这个路径。这也就意味着,getUsers方法实际上映射到了路径上。在Spring框架中,注解不仅可以应用于类级别,同样也可以应用于方法级别。 阅读详情

相关推荐

threekingdoms.txt中文三国演义下载及实现人物出场统计

threekingdoms.txt全文下载:https://python123.io/resources/pye/threekingdoms.txt CalThreeKingdomsV1.py: #CalThreeKingdomsV1.py import jieba txt = open("threekingdoms.txt", "r", encoding = "utf-8").read() words = jieba.lcut(txt) counts = {} for word in words:

ZYYRWish_97的博客 1万+

springMVC中的@requestmapping 的原理分析。

1 代码启动类会有注解@EnableWebMvc 2 打开该注解。发现里面有代码 3 打开DelegatingWebMvcConfiguration 发现里面并未定义什么东西,都是一些方法。于是找其父类。WebMvcConfigurationSupport 4 WebMvcConfigurationSupport 中定义了一个bean,这里说一句,@enable**类型的启用注解,...

LIUHUA121的博客 2355

SIwave:在 SIwave 中释放计算频率扫描的强大功能

AEDT 的电路工具允许注入正确的电压和电流。要使用电路工具,SIwave 必须首先使用 PI 求解器求解结构的 S 参数。

jkh920184196的博客 1474

RequestMapping的加载过程

注册过程的具体实现主要在RequestMappingHandlerMapping类中, 该类实现了InilizationBean接口中的afterPropertiesSet()接口, 调用其父类的该方法实现中完成加载.@RequestMapping可以声明类和方法对应的URL路径, 这些对应关系被注册在HandlerMapping中, 本文通过源码分析注册过程。processCandidateBean()中对候选进行筛选, 并检测其所有方法。最终被注册到一个map中, key->value如下。

weixin_44224362的博客 213

Frida实战:如何用HashMap.put拦截法快速定位安卓App加密参数(附完整脚本)

本文详细介绍了如何使用Frida拦截HashMap.put方法快速定位安卓App加密参数,提供完整脚本和实战案例。通过动态分析技术,相比传统静态分析大幅提升效率,适用于电商、社交、金融等场景的加密参数定位。

jump7的博客 260

电子取证之服务器取证思路

服务器取证是一个技术性很强的领域,涉及到多个环节,包括网站重构、网站代码分析、容器分析等。数据库密码的获取通常通过查看配置文件、日志文件、备份等途径,同时可以通过一些绕过技术如禁用身份验证来获取权限。对于不同的数据库,需要根据其特性采取相应的应对方法和命令。

2401_84830066的博客 2486

Spring MVC处理请求源码分析

《Spring Boot源码博客》 Spring MVC核心流程如下 1、系统启动阶段初始化请求和Controller方法的映射集合。 2、系统运行时,根据请求查找对应的Controller方法并获取请求参数。 3、通过反射执行Controller方法。 4、处理返回结果 ...

CodingSoldier的博客 446

MIPI D-PHY TX 一致性测试实例解析 Part 01 续

本文为MIPI D-PHY TX一致性测试实例解析part01章节的第二部分

一只豌豆象的博客 6041

SpringMVC源码:HandlerMapping加载2

但是在我们的日常开发中,handler大部分是一个使用@RequestParam修饰的一个方法,比如这样。

CRUD工程师 556

【实现100个unity特效之4】Unity ShaderGraph使用教程与各种特效案例(2023/12/1更新)

ShaderGraph是Unity中的一个可视化工具,用于创建和编辑图形着色器。其意义在于简化编写复杂着色器的过程,减少对具体编程语言的依赖,使艺术家和设计师可以更方便地创建各种美术效果。使用ShaderGraph可以通过图形界面设置着色器属性,包括颜色、纹理、光照等,并在视窗预览中即时显示结果,从而快速迭代和调整着色器。使用ShaderGraph需要先安装Unity 2018.1或以上版本,并添加ShaderGraph插件。打开ShaderGraph面板后,可以通过拖放节点并连接它们来创建着色器。

向宇的博客,专注php/web全栈 unity游戏开发,欢迎大家评论纠错 4万+

Arcgis栅格裁剪批处理工具

Arcgis栅格裁剪批处理工具

yilvyangguang520的博客 2172

Spring MVC之@RequestMapping 详解

本文详细解析了Spring MVC中@RequestMapping注解的用法,主要分为三部分:1)value/method属性用于定义请求路径和HTTP方法;2)consumes/produces属性用于限制请求/响应的Content-Type;3)params/headers属性用于校验请求参数和请求头。通过多个代码示例展示了路径变量、正则表达式匹配、内容类型限制等典型应用场景。文章最后指出,后续将探讨请求数据绑定和响应处理的相关内容。全文系统性地总结了@RequestMapping的核心功能

ywl470812087的博客 14万+

当启动容器的时候提示:exec format error?如何解决问题

Docker容器出现"exec format error"的主要原因是架构不兼容(如ARM设备运行x86镜像)。解决方案包括:1)匹配镜像与宿主机架构;2)构建时指定平台;3)安装QEMU模拟器;4)修复文件权限和格式;5)验证基础镜像兼容性。排查流程应从检查架构匹配开始,逐步验证权限、解释器和换行符等问题。建议优先使用多架构镜像,构建时明确指定平台,并使用buildx工具生成多平台镜像。调试时可进入容器手动验证文件格式和兼容性。

weixin_39291964的博客 2716

【Spring MVC】@RequestMapping 详解

RequestMapping注解一共有8个属性,常用的有value属性、method属性,其它6个属性往往容易被忽视,因此本文将逐一介绍这8个属性的作用及用法示例代码依赖版本如下。

Hi there 3830

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

NTscan扫描工具

ntscan是一个扫描器,可以扫描没有密码和弱密码的共享,先到配置文件中填写猜测的用户名和密码,扫描过程中右侧出现的是扫描日志。

spring mvc注解@RequestMapping的作用及属性

目录 一、@RequestMapping注解的作用是什么? 二、@RequestMapping注解的属性有哪些? 一、@RequestMapping注解的作用是什么? @RequestMapping注解是web应用程序中最常被用到的注解之一,作用就是映射URL路径,将http的请求地址映射到控制器(controller)类的处理方法上。 @RequestMapping注解可以定义在控制器类上,也可以定义在类里面的方法上。 定义类上:将http请求映射到该控制器上,规定初步的请...

冰冻非一日之寒 1万+

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

Spring MVC 教程-@Controller、@RequestMapping

RequestMaping中value、path、consumers、producers稍微用到的多一些,其他几个属性用到的比较少,了解即可。关于6种规则,大家可以自己去试试,会springboot的朋友,可以直接使用springboot快速写一些用例结合postman测试下,加深记忆和理解。

smart_an的专栏 1232

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

Spring MVC 中@RequestMapping 注解是如何工作的?

Spring MVC 中@RequestMapping 注解是如何工作的?

专注于技术分享 1434

Spring 的MVC @RequestMapping

这篇文章对Spring 的MVC @RequestMapping讲解的很清楚,摘记备忘. @Controller @RequestMapping("/appointments") public class AppointmentsController {     private final AppointmentBook appointmentBook;          @Aut

2441

Spring MVC 解读——@RequestMapping详解(一)

转自:https://my.oschina.net/HeliosFly/blog/212329 为了降低文章篇幅,使得文章更目标化,简洁化,我们就不例举各种@RequestMapping的用法等内容了. 文章主要说明以下问题: Spring怎样处理@RequestMapping(怎样将请求路径映射到控制器类或方法) Spring怎样将请求分派给正确的...

lukabruce的博客 507

Spring MVC @RequestMapping注解

简介 @RequestMapping注解是一个用来处理请求地址映射的注解,相当于Servlet中在web.xml中配置的映射作用一致,在控制器的类定义及方法定义处都可以标注。 用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。 DispatcherServlet截获请求后,通过控制器上@RequestMapping提供的映射信息确定请求所对应的处理方法。 @RequestMap...

Hern(宋兆恒) 610

Spring MVC @Controller和@RequestMapping注解

Spring 2.5 版本新增了 Spring MVC 注解功能,用于替换传统的基于 XML 的 Spring MVC 配置。 在《[第一个Spring MVC应用]》一节中创建了两个传统风格的控制器,它们是实现 Controller 接口的类。传统风格的控制器不仅需要在配置文件中部署映射,而且只能编写一个处理方法,不够灵活。 使用基于注解的控制器具有以下 2 个优点: 在基于注解的控制器类中可以编写多个处理方法,进而可以处理多个请求(动作),这就允许将相关的操作编写在同一个控制器类中,从而减少控制器类的

洛卡JAVA架构师每日分享Java架构师知识 450

Spring MVC中@RequestMapping注解的全面解析

在Spring MVC框架中,注解是处理请求映射的核心注解。它用于将请求和控制器方法关联起来,实现请求的映射和处理。以下是注解的详细介绍。

m0_74824802的博客 999

Spring MVC —— @RequestMapping

在POJO类定义处标注@Controller,再通过<context:component-scan />扫描相应的类包,即可使POJO成为一个能处理HTTP请求的控制器。 可以创建数量不限的控制器,分别处理不同的业务请求,如LogonController、UserController、ForumController等。每个控制器可拥有多个处理请求的方法,每个方法负责不同的请求操作。如何将

tuxq5721 2763

Spring mvc @RequestMapping 注解使用技巧

@RequestMapping 是 Spring Web 应用程序中最常被用到的注解之一。这个注解会将 HTTP 请求映射到 MVC 和 REST 控制器的处理方法上。  在这篇文章中,你将会看到 @RequestMapping 注解在被用来进行 Spring MVC 控制器方法的映射可以如何发挥其多才多艺的功能的。 Request Mapping 基础用法  在 Spring MVC 应用程序中...

u013161431的博客 488

Spring MVC 请求映射处理:@RequestMapping 与 @Pathvariable

@RequestMapping 注解是 Spring MVC 框架中一个用来映射请求到方法的注解,可用于类级别和方法级别。在类级别上,@RequestMapping 注解用于指定该控制器类处理的根路径或公共路径前缀。在方法级别上,@RequestMapping 注解用于指定具体的请求路径。可以将 @RequestMapping 注解与其他请求元数据一起使用,例如请求方法,请求类型、请求参数等,以更精确地映射请求。

JiaHao汤 1488
上一篇: 深入探索spring技术内幕(七): 配置Spring AOP面向切面编程
下一篇: SpringMVC核心分发器DispatcherServlet分析[附带源码分析]
god_love_hlq_xff
博客等级 码龄11年 27粉丝 37原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值