1. 整体目录结构microservice-demo父工程 ├── pom.xml父POM管理版本 ├── common公共模块 │ ├── pom.xml │ └── src/main/java/com/demo/common/ │ ├── dto/User.java │ └── api/UserApi.java ├── service-b服务提供方端口8081 │ ├── pom.xml │ ├── src/main/java/com/demo/serviceb/ │ │ ├── ServiceBApplication.java │ │ └── controller/UserController.java │ └── src/main/resources/application.yml └── service-a服务调用方端口8080 ├── pom.xml ├── src/main/java/com/demo/servicea/ │ ├── ServiceAApplication.java │ └── controller/OrderController.java └── src/main/resources/application.yml2. 父工程 pom.xml根目录?xml version1.0 encodingUTF-8?projectxmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdmodelVersion4.0.0/modelVersiongroupIdcom.demo/groupIdartifactIdmicroservice-demo/artifactIdversion1.0.0/versionpackagingpom/packaging!-- 引入 Spring Boot 父依赖统一版本 --parentgroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-parent/artifactIdversion2.7.14/versionrelativePath//parent!-- 管理 Spring Cloud 版本 --propertiesjava.version8/java.versionspring-cloud.version2021.0.8/spring-cloud.version/propertiesdependencyManagementdependenciesdependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-dependencies/artifactIdversion${spring-cloud.version}/versiontypepom/typescopeimport/scope/dependency/dependencies/dependencyManagementmodulesmodulecommon/modulemoduleservice-b/modulemoduleservice-a/module/modules/project3. common 模块定义 API 契约common/pom.xml?xml version1.0 encodingUTF-8?projectxmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdmicroservice-demo/artifactIdgroupIdcom.demo/groupIdversion1.0.0/version/parentmodelVersion4.0.0/modelVersionartifactIdcommon/artifactIddependencies!-- 必备包含 FeignClient 注解 --dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-openfeign/artifactId/dependency!-- 必备包含 GetMapping, PathVariable 等注解 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency!-- 为了少写 getter/setter引入 Lombok可选 --dependencygroupIdorg.projectlombok/groupIdartifactIdlombok/artifactIdoptionaltrue/optional/dependency/dependencies/projectcommon/src/main/java/com/demo/common/dto/User.javapackagecom.demo.common.dto;importlombok.Data;Data// 自动生成 getter/setter/toStringpublicclassUser{privateLongid;privateStringname;privateStringemail;}common/src/main/java/com/demo/common/api/UserApi.javapackagecom.demo.common.api;importcom.demo.common.dto.User;importorg.springframework.cloud.openfeign.FeignClient;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PathVariable;// name service-b 对应 B 服务的 spring.application.name// path /api 统一前缀方便 B 服务统一管理// 这里暂时写死 url方便不接注册中心直接运行接入注册中心时删掉 url 即可FeignClient(nameservice-b,urlhttp://localhost:8081,path/api)publicinterfaceUserApi{GetMapping(/users/{id})UsergetUserById(PathVariable(id)Longid);}4. service-b 模块服务提供方实现接口service-b/pom.xml?xml version1.0 encodingUTF-8?projectxmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdmicroservice-demo/artifactIdgroupIdcom.demo/groupIdversion1.0.0/version/parentmodelVersion4.0.0/modelVersionartifactIdservice-b/artifactIddependencies!-- 依赖 common 模块 --dependencygroupIdcom.demo/groupIdartifactIdcommon/artifactIdversion1.0.0/version/dependency!-- web 容器 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency/dependencies/projectservice-b/src/main/resources/application.ymlserver:port:8081spring:application:name:service-b# 必须和 FeignClient(name service-b) 保持一致service-b/src/main/java/com/demo/serviceb/ServiceBApplication.javapackagecom.demo.serviceb;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;SpringBootApplication// 重点注意B 服务是提供方这里绝对不能加 EnableFeignClientspublicclassServiceBApplication{publicstaticvoidmain(String[]args){SpringApplication.run(ServiceBApplication.class,args);}}service-b/src/main/java/com/demo/serviceb/controller/UserController.javapackagecom.demo.serviceb.controller;importcom.demo.common.api.UserApi;importcom.demo.common.dto.User;importorg.springframework.web.bind.annotation.RestController;RestController// 关键点实现 common 中定义的接口自动继承 GetMapping 路径publicclassUserControllerimplementsUserApi{OverridepublicUsergetUserById(Longid){// 模拟数据库查询返回假数据UserusernewUser();user.setId(id);user.setName(张三来自B服务);user.setEmail(zhangsanservice-b.com);returnuser;}}5. service-a 模块服务调用方使用 Feignservice-a/pom.xml?xml version1.0 encodingUTF-8?projectxmlnshttp://maven.apache.org/POM/4.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsdparentartifactIdmicroservice-demo/artifactIdgroupIdcom.demo/groupIdversion1.0.0/version/parentmodelVersion4.0.0/modelVersionartifactIdservice-a/artifactIddependencies!-- 依赖 common 模块 --dependencygroupIdcom.demo/groupIdartifactIdcommon/artifactIdversion1.0.0/version/dependencydependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-web/artifactId/dependency/dependencies/projectservice-a/src/main/resources/application.ymlserver:port:8080spring:application:name:service-aservice-a/src/main/java/com/demo/servicea/ServiceAApplication.javapackagecom.demo.servicea;importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;importorg.springframework.cloud.openfeign.EnableFeignClients;SpringBootApplication// 必须加此注解并指定扫描 common 模块中 Feign 接口所在的包EnableFeignClients(basePackagescom.demo.common.api)publicclassServiceAApplication{publicstaticvoidmain(String[]args){SpringApplication.run(ServiceAApplication.class,args);}}service-a/src/main/java/com/demo/servicea/controller/OrderController.javapackagecom.demo.servicea.controller;importcom.demo.common.api.UserApi;importcom.demo.common.dto.User;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.GetMapping;importorg.springframework.web.bind.annotation.PathVariable;importorg.springframework.web.bind.annotation.RestController;RestControllerpublicclassOrderController{AutowiredprivateUserApiuserApi;// 直接注入 common 里的接口GetMapping(/order/{id}/user)publicUsergetOrderUser(PathVariable(id)Longid){// 看上去像本地调用实际上发起了 HTTP 请求给 service-breturnuserApi.getUserById(id);}}6. 运行测试先启动 service-b右键运行ServiceBApplication.main控制台看到Started ServiceBApplication on port 8081。再启动 service-a右键运行ServiceAApplication.main控制台看到Started ServiceAApplication on port 8080。打开浏览器或 Postman访问http://localhost:8080/order/123/user返回结果JSON{id:123,name:张三来自B服务,email:zhangsanservice-b.com}7. 特别提示再强调一遍检查项说明B 服务启动类绝对不要加EnableFeignClients否则它会尝试把自己注册成 Feign 客户端而报错。A 服务启动类必须加EnableFeignClients(basePackages com.demo.common.api)否则UserApi无法被注入报NoSuchBeanDefinitionException。common 依赖如果common模块打包报错记得先mvn clean install安装到本地仓库再启动 A 和 B。路径一致性B 服务的UserController由于实现了接口不要再写RequestMapping在类上否则路径会变成双份如/api/api/users。