【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方 ...
随机推荐
- REM——适合移动开发的自适应方案
文章目录 1.什么是REM 2.REM和EM的区别 3.手机端方案的特点 4.使用JS动态调整REM 5.REM与其他单位同时存在 1.什么是REM 先来认识几个常见单位: px:像素,这个大家都知道 ...
- 意识科学初步:David Chalmers的简单问题与困难问题
这是第一篇关于意识科学的内容.主要谈一下阅读大卫查莫斯的几篇论文的一些观点和思考. 论文作者简介(摘自wiki): David John Chalmers (born 20 April 1966) i ...
- AES加密算法详解
AES 是一个对称密码分组算法,分组长度为128bit,密钥长度为128.192 和 256 bit. 整个加密过程如下图所示. 1.密钥生成算法 密钥扩展过程: 1) 将种子密钥按下图所示的格式排 ...
- CSS引用方式及样式层叠机制
CSS引用方式有3种,三种分别为:外部引入.内部引入.行内样式,下面一 一进行介绍. 1.外部引入:CSS代码在一个独立的文件中,HTML通过Link标签引入到页面. 代码格式:<link re ...
- d3.js,初遇
接触d3完全是由兴趣所致,废话不多说看代码: var dataArray = [23, 13, 21, 14, 37, 15, 18, 34, 30];这是这个图所需要的数据,其实这个柱状图最初不长这 ...
- python从入门到实践-5章if语句
#!/user/bin/env python cars = ['audi','bmw','subaru','toyota']for car in cars: if car == 'bmw': prin ...
- 神经网络_线性神经网络 2 (Nerual Network_Linear Nerual Network 2)
1 LMS 学习规则 1.1 LMS学习规则定义 MSE=(1/Q)*Σe2k=(1/Q)*Σ(tk-ak)2,k=1,2,...,Q 式中:Q是训练样本:t(k)是神经元的期望输出:a(k)是神经元 ...
- JS闭包解析
三点注意事项 JS作用域传送门 JS没有块级作用域,只有全局作用域和局部作用域(函数作用域). JS中的作用域链,内部的作用域可以访问到外部作用域中的变量和方法,而外部作用域不能访问内部作用域的变量和 ...
- MySQL 的分页查询 SQL 语句
MySQL一般使用 LIMIT 实现分页.基本语句为: SELECT ... FROM ... WHERE ... ORDER BY ... LIMIT ... 在中小数据量的情况下,这样的SQL足够 ...
- [Swift]LeetCode996. 正方形数组的数目 | Number of Squareful Arrays
Given an array A of non-negative integers, the array is squareful if for every pair of adjacent elem ...