OpenFeign不是通过“反射读取 GetMapping 来拿 URL 并直接拼出来调用”的简单模型它的实现要更“分层”本质是启动时解析注解 → 生成 Method 元数据 → 运行时动态代理 Contract 解释 → RequestTemplate 构建 URL一、先给结论面试级Feign 不是运行时反射拼 URL 而是 启动时解析 Spring MVC 注解 → 生成 MethodMetadata → 调用时由 Contract 生成 RequestTemplate → 再由 Encoder Client 发 HTTP 请求二、你提到的点GetMapping 是什么时候被处理的例如FeignClient(user-service) public interface UserClient { GetMapping(/user/{id}) User get(PathVariable Long id); }❌ 错误理解常见误区运行时反射 GetMapping → 直接拿 URL 不是这样✅ 正确流程1️⃣ 启动阶段扫描 Feign 接口Spring Boot 启动时FeignClientsRegistrar扫描FeignClient2️⃣ 解析方法上的注解这里才“读取GetMapping”由SpringMvcContract做解析。它会读取GetMapping(/user/{id}) PathVariable RequestParam3️⃣ 生成 MethodMetadata关键Feign不会直接存 URL而是存MethodMetadata { methodName: get, url: /user/{id}, httpMethod: GET, params: [id] }三、运行时发生什么调用userClient.get(1L);进入FeignInvocationHandler.invoke()1️⃣ 创建 RequestTemplate核心RequestTemplate内容GET /user/{id}2️⃣ 参数替换不是反射是模板绑定{id} → 1变成GET /user/13️⃣ 选择服务实例负载均衡来自Nacos / Eurekauser-service: 10.0.0.1:8080 10.0.0.2:8080选一个10.0.0.1:80804️⃣ 拼成完整 URLhttp://10.0.0.1:8080/user/15️⃣ HTTP Client发送请求例如OkHttpApache HttpClientJDK HttpClient四、关键点总结面试重点❗ Feign不是“反射调用注解”而是1. 启动时解析注解SpringMvcContract 2. 构建方法元数据MethodMetadata 3. 运行时生成 RequestTemplate 4. 再拼URL 发HTTP请求五、为什么不能简单用反射如果只是反射method.getAnnotation(GetMapping.class)问题❌ 1. 无法处理路径变量/user/{id}❌ 2. 无法统一参数绑定规则PathVariable RequestParam RequestBody❌ 3. 无法支持复杂扩展拦截器 重试 负载均衡 熔断六、Feign核心设计思想一句话Feign 注解解析 方法模板 HTTP执行器不是反射 直接拿URL