【API知识】一种你可能没见过的Controller形式
前言
这里分享一下我遇到的一个挺有意思的Controller形式,内容涉及@RequestMapping注解的原理。
实际案例
一、基本描述
项目甲中有多个模块,其中就有模块A和B。(这里的模块指的是Maven的多模块子项目),项目乙、丙、丁可以引用模块A来访问独立部署的模块B
模块A => 关于与模块B通信的协议定义
模块B => 可以独立部署的项目
其中模块A中定义了一个FeignClient的接口用于访问模块B的服务。
@FeignClient(name = "xx-service", url="http://xx-service:8080")
public interface XXXService {
@PostMapping("/some-url")
public SomeResponse someOperation(@RequestBody SomeParam param);
...
}
我们知道只要打上了@FeignClient注解,我们就可以直接在类中引入这个XXXService,然后调用它的方法。如果我们调用someOperation方法,那它就会根据服务名获取到IP端口信息,然后发HTTP请求到指定服务xx-service。
二、问题出现
按理说,模块B肯定有一个Controller来处理这个“/som-url”的请求。于是我全局搜索了模块B,发现怎么找也找不到“/some-url”。
后来发现模块B中依赖于模块A,且有一个类实现了XXXService这个接口。这个类叫XXXServiceImpl。这个类既不叫xxxController,也不带@Controller注解。
@ResponseBody
@RequestMapping
@Service
public class XXXServiceImpl implements XXXService {
@Override
public SomeResponse someOperation(SomeParam param) {
SomeResponse someResponse = new SomeResponse();
...
return someResponse;
}
...
}
看到@ResponseBody,@RequestMapping,@Service。在我看来这就是一个@RestController了。但是问题来了,还是没有Mapping。
三、我的一个猜想
我想有没有可能实现类继承了接口方法上的注解,于是我看了下@PostMapping的元注解,发现并没有@Inherited的注解。我也尝试打印了XXXServiceImpl类someOperation方法上的注解,发现确实没有。
四、问题解答
XXXServiceImpl确实充当了Controller。关键在于针对@RequestMapping的扫描,会向上扫描类的所有父类和接口。只要在接口或者父类的上方法上发现了@RequestMapping的注解,就认定这个方法是某个请求关联的处理方法。
简化版本
可能有人不是很理解前面的实际案例,这里提供一个简化的版本。
一、新建一个只带Web的Spring Boot项目

二、定义一个接口
这个接口有一个方法,带有@GetMapping注解。
public interface ControllerInterface {
@GetMapping("/hello")
String hello();
}
三、添加实现类
@RequestMapping
@ResponseBody
@Service
public class ControllerInterfaceImpl implements ControllerInterface {
@Override
public String hello() {
return "hello world";
}
}
四、启动并测试
启动项目,访问http://localhost:8080/hello

发现确实可以访问。实际上组合方式还有很多,你可以把注解都写在接口上。
@RequestMapping原理简述
一、搜寻处理类
一个类上如果有@Controller或者@ReqeustMapping注解,会被认定为是请求的Handler。
二、搜寻处理方法
找到处理类后,第二步就是在处理类中查找处理方法,即标注有@RequestMapping(或者其他变种)的方法,注意这里扫描的过程中,会向上扫描父类或者接口是否带有此注解。这个操作由HandlerMethodSelector来完成(Spring 4有这个类,后面的版本可能名称有所变更)
三、整合URL生成RequestMappingInfo
如果处理类上有@RequestMpping注解,且有设置url,则会将类上和方法上的URL拼接起来。最终形成一个RequestMappingInfo。
四、生成映射关系
每个RequestMappingInfo会映射到一个处理方法HandlerMethod。
参考资料
【API知识】一种你可能没见过的Controller形式的更多相关文章
- Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式 目录 Pycharm使用技巧(转载) Python第一天 安装 shell 文件 Py ...
- 这是你没见过的不一样的redis
转: 这是你没见过的不一样的redis 提到Redis,大家一定会想到的几个点是什么呢? 高并发,KV存储,内存数据库,丰富的数据结构,单线程(6版本之前) 那么,接下来,上面提到的这些,都会一一给大 ...
- 超赞!12套你没见过的社交媒体 & 社交网站图标
如今,社交网络成为我们信息获取和传播的重要途径,很多网站都有把内容分享到社交媒体的功能.社交媒体图标作为向用户传递信息的重要媒介,不管是在网页还是 Web 应用程序中都非常需要.今天这篇文章和大家分享 ...
- struts2的action访问servlet API的三种方法
学IT技术,就是要学习... 今天无聊看看struts2,发现struts2的action访问servlet API的三种方法: 1.Struts2提供的ActionContext类 Object g ...
- Action访问Servlet API的三种方法
一.为什么要访问Servlet API ? Struts2的Action并未与Servlet API进行耦合,这是Struts2 的一个改良,从而方便了单独对Action进行测试.但是对于Web控制器 ...
- 【.Net】调用Web API的几种方式
引言 记录一下调用Web API的几种方式,以调用百度API为例. HttpWebRequest HttpWebRequest位于System.Net命名空间,是常用的调用Web API类库. str ...
- Vue.js 2.x API 知识梳理(一) 全局配置
Vue.js 2.x API 知识梳理(一) 全局配置 Vue.config是一个对象,包含Vue的全局配置.可以在启动应用之前修改指定属性. 这里不是指的@vue/cli的vue.config.js ...
- 在C#中使用RESTful API的几种好方法
什么是Restful API REST 即Representational State Transfer的缩写.直接翻译的意思是"表现层状态转化". 它是一种互联网应用程序的API ...
- Queue API的几种实现详解
目录 Queue API的几种方法的使用 ArrayBlockingQueue原理及源码解析 ArrayBlockingQueue的成员变量 ArrayBlockingQueue的offer和put方 ...
随机推荐
- LPC 语言基础
LPC是一种基于C语言开发的编程语言 主要用于写MUD(多使用着迷宫)游戏 LPC是一种面向对象的语言,它有object的概念,但是没有class LPC有四中函数类型1> apply 只能被游 ...
- delphi 鼠标拖动
GetWindowRect(tgph, Rect); //获得窗体大小 setcursorpos(Rect.Left + 487, Rect.Top + 274); delay(100); mouse ...
- acl权限命令
1.查看acl命令 getfacl 文件名 #查看acl权限 2.设定acl权限命令 setfacl 选项 文件名 选项: -m 设置ACL权限 -x 删除指定的ACL权限 -b 删除所有的ACL设定 ...
- SPA 单页面应用程序。
看到这个问题,先说下自己的理解到的程度,再去参考做修正,争取这一次弄懂搞清楚 自己的理解: 单页面应用程序,解决浏览器获取数据刷新页面的尴尬,通过ajax请求获取数据达到异步更新视图的按钮,原理的实现 ...
- Linux 系统中的内部与外部命令
linux中的命令大致可分为两类,内部命令和外部命令: 内部命令(builtin command):也称shell内嵌命令 外部命令(external command):存放在一个文件中,使用时需要去 ...
- FCC(ES6写法) Friendly Date Ranges
把常见的日期格式如:YYYY-MM-DD 转换成一种更易读的格式. 易读格式应该是用月份名称代替月份数字,用序数词代替数字来表示天 (1st 代替 1). 包含当前年份和相同月份的时候,makeFri ...
- 基于docker搭建开源扫描器——伏羲
基于docker搭建开源扫描器——伏羲 1.简介 项目地址 伏羲是一款开源的安全检测工具,适用于中小型企业对企业内部进行安全检测和资产统计. 功能一览: 基于插件的漏洞扫描功能(类似于巡风) 漏洞管理 ...
- 分门别类总结Java中的各种锁,让你彻底记住
概念 公平锁/非公平锁 公平锁是指多个线程按照申请锁的顺序来获取锁. 非公平锁是指多个线程获取锁的顺序并不是按照申请锁的顺序,有可能后申请的线程比先申请的线程优先获取锁.有可能,会造成优先级反转或者饥 ...
- Javascript高级编程学习笔记(92)—— Canvas(9) 渐变
渐变 渐变由 canvasGradient 实例表示 要创建一个渐变对象需要调用 createLinearGradient() 方法 该方法接收四个参数: 起点的x坐标 起点的y坐标 终点的x坐标 终 ...
- [Swift]LeetCode933. 最近的请求次数 | Number of Recent Calls
Write a class RecentCounter to count recent requests. It has only one method: ping(int t), where t r ...