Spring Boot多模块无依赖跨模块调用REST API的404及SSO问题解决
Spring Boot 多模块同应用跨模块REST调用问题
项目基础背景
- 项目为Spring Boot多模块架构,包含Module A、Module B两个模块,现有依赖关系为 Module A 依赖 Module B,反向引入依赖会触发循环依赖问题
- Module A 中定义了如下GET接口:
@GetMapping(path = "/getworkspaces") public Map<String, Object> getWorkSpaces() { Map<String, Object> workspaces = null; workspaces = this.dataSetService.getWorkSpaces(); return workspaces; }
现有实现与异常表现
- Module B 需要调用上述Module A的接口,当前实现逻辑为:
public String consumeModuelAMethod() { RestTemplate restTemplate = new RestTemplate(); String url = "http://localhost:8080/getworkspaces" try { ResponseEntity<String> responseMap = restTemplate.getForEntity(url, String.class); if (HttpStatus.OK.equals(responseMap.getStatusCode())){ return responseMap.getBody(); }else { return null; } } catch (RestClientException ex){ex.printStackTrace();} }
- 具体异常:调用
http://localhost:8080/getworkspaces时返回404 Not Found错误 - 项目全局启用SSO单点登录安全防护,所有接口均接入鉴权拦截逻辑
- 实现约束:不能新增模块间的编译依赖,不能调整现有依赖方向结构,需实现同一应用进程内不同模块间的REST API调用
问题根因排查
- 代码语法错误:原实现中url赋值的语句末尾缺少分号,会直接导致编译失败,接口调用逻辑无法正常生效
- 路径配置偏差:检查Module A对应Controller的类级
@RequestMapping路径,若存在全局接口前缀(如统一配置的/api路径前缀),而调用时遗漏对应前缀,会直接触发404;同时需校验应用实际启动端口是否与调用地址配置的8080一致,避免端口占用、随机端口启动导致的路径不匹配 - 鉴权拦截误判:SSO拦截器通常会对未携带有效鉴权信息的请求直接返回404(而非403),以此避免暴露接口的真实存在性,未传递SSO鉴权上下文的请求会被拦截器标记为不存在的路径
- 链路冗余问题:当前实现通过真实HTTP网络请求访问本机端口,同进程内跨模块调用不需要走完整的网络监听链路,本身存在不必要的性能开销与配置兼容风险
无额外依赖的实现方案
同进程内跨模块调用完全不需要发起真实网络请求,可在不新增模块编译依赖的前提下,通过内存级路由完成接口调用:
- 替换原RestTemplate的请求工厂实现:移除直接
new RestTemplate的硬编码写法,将RestTemplate的请求链路绑定到应用内部的DispatcherServlet,所有指向应用本身的URL请求直接在内存中路由到对应接口方法,绕开真实端口监听、网络栈校验环节 - 鉴权上下文透传:在内部路由调用时,将当前线程上下文中的SSO鉴权信息同步传递到路由链路中,不需要额外请求获取token,即可通过SSO拦截器的校验
- 落地注意事项:
- 不要在Module B中直接引入Module A的接口类做编译依赖,避免依赖方向反转触发循环依赖
- 不要在调用地址中硬编码固定端口,适配多实例、随机端口启动的部署场景
- 内部调用的请求路径需要与Controller的实际映射路径完全对齐,避免漏写全局前缀导致的404
内容的提问来源于stack exchange,提问作者FaizUR Rahman
相关产品推荐
相关产品推荐

