千家信息网

RequestMapping要写在Controller类里吗

发表于:2026-10-31 作者:千家信息网编辑
千家信息网最后更新 2026年10月31日,本篇内容介绍了"RequestMapping要写在Controller类里吗"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔
千家信息网最后更新 2026年10月31日RequestMapping要写在Controller类里吗

本篇内容介绍了"RequestMapping要写在Controller类里吗"的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!

使用Spring Cloud做项目的同学会使用Feign这个组件进行远程服务的调用,Feign这个组件采用模板的方式,有着优雅的代码书写规范。核心原理对Feign等相关注解进行解析,并提取信息,在Spring Boot工程启动时,通过反射生产Request的bean,并将提取的信息,设置到bean中,最后注入到ioc容器中。

现在有这样的场景,服务A提高RestApi接口,服务B、C、D等服务需要调用服务A提供的RestApi接口,这时最常见的做法是在服务B、C、D分别写一个FeignClient,并需要写RestApi接口的接收参数的实体和接收响应的实体DTo类。这样的做法就是需要不停复制代码。

有没有办法简洁上面的操作呢?有一种最常见的做法是将将服务A进行模块拆分,将FeignClient和常见的model、dto对外输出的类单独写一个模块,可以类似于取名a-service-open_share。这样将服务A服务分为两个模块,即A服务的业务模块和A服务需要被其他服务引用的公共类的模块。服务B、C、D只需要引用服务A的a-service-open_share就具备调用服务A的能力。

笔者在这里遇到一个有趣的其问题。首先看问题:

写一个FeignClient:

@FeignClient(name = "user-service")public interface UserClient {    @GetMapping("/users")    List getUsers();

写一个实现类:

@RestControllerpublic class UserController implements UserClient {    @Autowired    UserService      userService;    @OverRide    List getUsers(){       return userService.getUsers();    }

启动工程,浏览器访问接口localhost:8008/users,竟然能正确访问?!明明我在UserController类的getUsers方法没有加RequestMapping这样的注解。为何能正确的映射?!

带着这样的疑问,我进行了一番的分析和探索!

首先就是自己写了一个demo,首先创建一个接口类:

public interface ITest {    @GetMapping("/test/hi")    public String hi();}

写一个Controller类TestController

@RestControllerpublic class TestController implements ITest {    @Override    public String hi() {        return "hi you !";    }

启动工程,浏览器访问:http://localhost:8762/test/hi,浏览器显示:

hi you !

我去,TestController类的方法 hi()能够得到ITest的方法hi()的 @GetMapping("/test/hi")注解吗? 答案肯定是获取不到的。

特意编译了TestController字节码文件:
javap -c TestController

 public class com.example.demo.web.TestController implements com.example.demo.web.ITest {  public com.example.demo.web.TestController();    Code:       0: aload_0       1: invokespecial #1                  // Method java/lang/Object."":()V       4: return  public java.lang.String hi();    Code:       0: ldc           #2                  // String hi you !       2: areturn}

上面的字节码没有任何关于@GetMapping("/test/hi")的信息,可见TestController直接获取不到@GetMapping("/test/hi")的信息。

那应该是Spring MVC在启动时在向容器注入Controller的Bean(HandlerAdapter)时做了处理。初步判断应该是通过反射获取到这些信息,并组装到Controller的Bean中。首先看通过反射能不能获取ITest的注解信息:

 public static void main(String[] args) throws ClassNotFoundException {    Class c = Class.forName("com.example.demo.web.TestController");    Class[] i=c.getInterfaces();    System.out.println("start interfaces.."  );    for(Class clz:i){        System.out.println(clz.getSimpleName());        Method[] methods = clz.getMethods();        for (Method method : methods) {            if (method.isAnnotationPresent(GetMapping.class)) {                GetMapping w = method.getAnnotation(GetMapping.class);                System.out.println("value:" + w.value()[0]  );            }        }    }    System.out.println("end interfaces.."  );    Method[] methods = c.getMethods();    for (Method method : methods) {        if (method.isAnnotationPresent(GetMapping.class)) {            GetMapping w = method.getAnnotation(GetMapping.class);            System.out.println("value:" + w.value());        }    }}

允运行上面的代码:

start interfaces..

ITest

value:/test/hi

end interfaces..

可见通过反射是TestController类是可以获取其实现的接口的注解信息的。为了验证Spring Mvc 在注入Controller的bean时通过反射获取了其实现的接口的注解信息,并作为urlMapping进行了映射。于是查看了Spring Mvc 的源码,经过一系列的跟踪在RequestMappingHandlerMapping.java类找到了以下的方法:

protected RequestMappingInfo getMappingForMethod(Method method, Class handlerType) {   RequestMappingInfo info = createRequestMappingInfo(method);   if (info != null) {      RequestMappingInfo typeInfo = createRequestMappingInfo(handlerType);      if (typeInfo != null) {         info = typeInfo.combine(info);      }   }   return info;}

继续跟踪源码在AnnotatedElementUtils 类的searchWithFindSemantics()方法中发现了如下代码片段:

// Search on methods in interfaces declared locallyClass[] ifcs = method.getDeclaringClass().getInterfaces();result = searchOnInterfaces(method, annotationType, annotationName, containerType, processor,      visited, metaDepth, ifcs);if (result != null) {   return result;}

这就是我要寻找的代码片段,验证了我的猜测。

"RequestMapping要写在Controller类里吗"的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注网站,小编将为大家输出更多高质量的实用文章!

服务 信息 接口 注解 代码 方法 模块 反射 做法 就是 工程 常见 浏览器 面的 浏览 内容 字节 实体 容器 更多 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 天津市摩尔互联网科技 科技互联网产品 科技金融是不是互联网金融 互联网科技的 中国 科技 互联网 互联网科技股票 深圳齐家互联网科技 善班互联网科技有限公司 互联网女皇 腾讯科技 广州善班互联网科技 居家互联网科技有限公司 互联网科技与大数据专业 本届互联网博览会上的黑科技 美国互联网科技公司 35岁以上互联网科技行业 互联网公司属于科技吗 科技互联网专业务虚会材料 广东猫王互联网科技有限公司电话 互联网科技快速发展优美句子 颐高云石互联网科技 上海亿帐通互联网科技 太原新华互联网科技学校怎么样 电子科技大学互联网创业大赛 本届互联网博览会上的黑科技 河南住房之家互联网科技 玉溪新华互联网科技好不好 世界互联网领先科技成果获奖 烟台灵鸽互联网科技有限公司 众安科技工业互联网合作 每天都有哪些好的互联网科技
0