# 《Spring核心技术》第45章-方法映射:深度解析@RequestMapping注解
作者:冰河
星球:http://m6z.cn/6aeFbs (opens new window)
博客:https://binghe.gitcode.host (opens new window)
文章汇总:https://binghe.gitcode.host/md/all/all.html (opens new window)
源码地址:https://github.com/binghe001/spring-annotation-book/tree/master/spring-annotation-chapter-45 (opens new window)
沉淀,成长,突破,帮助他人,成就自我。
大家好,我是冰河~~
本章难度:★★★★☆
本章重点:进一步学习并掌握@RequestMapping注解注册映射关系和定位HandlerMethod的案例和流程,从源码级别彻底掌握@RequestMapping注解在Spring底层的执行流程。
本章目录如下所示:
- 学习指引
- 注解说明
- 注解源码
- 衍生注解
- 使用场景
- 使用案例
- 源码时序图
- 建立映射关系
- 定位处理方法
- 访问处理方法
- 源码解析
- 建立映射关系
- 定位处理方法
- 访问处理方法
- 容错处理机制
- 总结
- 思考
- VIP服务
# 一、学习指引
Spring中的@RequestMapping注解,你真的彻底了解过吗?
基于SpringMVC或者SpringBoot开发过Web应用程序的小伙伴,一定对@RequestMapping这个注解不陌生,在方法上标注了@RequestMapping注解后,通过某个链接就能够访问到对应的方法,那你知道@RequestMapping注解在源码层面的执行流程吗?
本章,就对@RequestMapping注解在源码层面的执行流程一探究竟。
# 二、注解说明
关于@RequestMapping注解的一点点说明~~
在类上标注了@Controller注解或者@RestController注解之后,同时方法上如果标注了@RequestMapping注解,则方法会和某个链接自动建立映射关系,通过链接地址就能够访问到对应的方法。
# 2.1 注解源码
@RequestMapping注解的源码详见:org.springframework.web.bind.annotation.RequestMapping。
/**
* @author Juergen Hoeller
* @author Arjen Poutsma
* @author Sam Brannen
* @since 2.5
* @see GetMapping
* @see PostMapping
* @see PutMapping
* @see DeleteMapping
* @see PatchMapping
*/
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Mapping
@Reflective(ControllerMappingReflectiveProcessor.class)
public @interface RequestMapping {
String name() default "";
@AliasFor("path")
String[] value() default {};
/**
* @since 4.2
*/
@AliasFor("value")
String[] path() default {};
/**
* GET, POST, HEAD, OPTIONS, PUT, PATCH, DELETE, TRACE.
*/
RequestMethod[] method() default {};
String[] params() default {};
/**
* RequestMapping(value = "/something", headers = "content-type=text/*")
*/
String[] headers() default {};
/**
* consumes = "text/plain"
* consumes = {"text/plain", "application/*"}
* consumes = MediaType.TEXT_PLAIN_VALUE
*/
String[] consumes() default {};
/**
* produces = "text/plain"
* produces = {"text/plain", "application/*"}
* produces = MediaType.TEXT_PLAIN_VALUE
* produces = "text/plain;charset=UTF-8"
*/
String[] produces() default {};
}
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
从源码可以看出,@RequestMapping注解是从Spring2.5版本开始提供的注解,可以标注到类和方法上,并且在@RequestMapping注解中提供了多个属性。
name:String类型的属性,为请求的URL指定一个名称。
value:String数组类型的属性,指定请求的URL。
path:从Spring4.2版本开始提供的String数组类型的属性,作用与value属性相同。
method:RequestMethod枚举数组类型的属性,用于指定请求的方法,取值可以为RequestMethod枚举类型中的GET, HEAD, POST, PUT, PATCH, DELETE, OPTIONS, TRACE。既可以指定单个RequestMethod枚举类型,也可以同时指定多个RequestMethod枚举类型,不指定时,表示处理所有的RequestMethod枚举类型。
params:String数组类型的属性,用于指定请求参数,支持简单的表达式,使用params属性时,要求请求的参数Key和Value必须与params属性中配置的Key和Value相同。例如下面的示例所示。
- @RequestMapping(value = "/binghe", params = {"userName"}):表示请求参数中必须有userName。
- @RequestMapping(value = "/binghe", params = {"userId = 1001"}):表示请求的参数中Key为userId,值为1001。
可以使用params属性实现同一个URL映射到不同的方法上,请求时根据不同的参数映射到不同的方法上。
headers:String数组类型的属性,用于指定请求头信息,主要是限制请求头的信息,当请求头中必须包含某些指定的头信息时,才能让方法处理请求。例如下面的示例所示。
- @RequestMapping(value = "/binghe", headers = "content-type=text/*")
consumes:String数组类型的属性,用于指定要接收的请求体(消息体)的类型,只有满足这些类型的请求才会被处理,不指定时,表示处理所有类型。取值可以参见:org.springframework.http.MediaType。例如下面的示例所示。
- @RequestMapping(value = "/binghe", consumes = {"text/plain", "application/*"})
- @RequestMapping(value = "/binghe", consumes = MediaType.TEXT_PLAIN_VALUE)
还有一点就是consumes属性支持类似逻辑非操作,例如下面的示例所示。
- @RequestMapping(value = "/binghe", consumes = {"!text/plain", "application/*"})
- @RequestMapping(value = "/binghe", consumes = !MediaType.TEXT_PLAIN_VALUE)
produces:String数组类型的属性,用于指定要响应的消息体的类型,指定的类型必须是请求头(Accept)中所包含的类型。当请求头(Accept)中包含指定的类型时才会响应结果,取值可以参见:org.springframework.http.MediaType。例如下面的实例所示。
- @RequestMapping(value = "/binghe", produces= {"text/plain", "application/*"})
- @RequestMapping(value = "/binghe", produces = MediaType.TEXT_PLAIN_VALUE)
还有一点就是produces属性支持类似逻辑非操作,例如下面的示例所示。
- @RequestMapping(value = "/binghe", produces = {"!text/plain", "application/*"})
- @RequestMapping(value = "/binghe", produces = !MediaType.TEXT_PLAIN_VALUE)
注意:使用@RequestMapping注解时,只要出现两个或以上的属性时,多个属性之间的关系是与关系,表示必须同时满足条件才会处理。
# 2.2 衍生注解
@RequestMapping注解还有五个衍生注解,分别如下所示。
# 查看完整文章
加入冰河技术 (opens new window)知识星球,解锁完整技术文章与完整代码