各位在微服务世界摸爬滚打的道友们!今天要解锁的是Spring Cloud的绝世神通——Feign!这货堪称HTTP界的"言出法随",只需定义接口,就能自动生成HTTP请求代码!从此告别手动拼装URL的苦日子,让你的代码优雅如诗! ✨
一、筑基篇:初识Feign
1.1 法宝祭炼(添加依赖)
<!-- Spring Cloud OpenFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>4.0.4</version> <!-- 2023最新版本 -->
</dependency>
1.2 开启Feign法阵
@SpringBootApplication
@EnableFeignClients // 激活Feign魔法
public class MyApp {
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
二、金丹篇:基础请求术
2.1 定义Feign接口(言出法随)
@FeignClient(name = "user-service", url = "https://api.example.com")
public interface UserClient {
@GetMapping("/users/{id}")
User getUserById(@PathVariable("id") Long id);
@PostMapping("/users")
User createUser(@RequestBody User user);
}
2.2 注入使用(召唤术)
@RestController
public class UserController {
@Autowired
private UserClient userClient; // Spring会自动实现接口!
@GetMapping("/proxy-user/{id}")
public User getProxyUser(@PathVariable Long id) {
return userClient.getUserById(id); // 直接调用!
}
}
三、元婴篇:高级神通
3.1 自定义配置(个性化法宝)
@FeignClient(name = "order-service",
url = "https://api.example.com",
configuration = OrderClientConfig.class)
public interface OrderClient {
// ...
}
// 配置类示例
public class OrderClientConfig {
@Bean
public Logger.Level feignLoggerLevel() {
return Logger.Level.FULL; // 开启详细日志
}
@Bean
public Retryer feignRetryer() {
return new Retryer.Default(1000, 2000, 3); // 自定义重试策略
}
}
3.2 拦截器(请求炼金术)
public class AuthInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
template.header("Authorization", "Bearer " + getToken());
}
private String getToken() {
// 获取JWT令牌的逻辑
}
}
// 注册拦截器
@Bean
public AuthInterceptor authInterceptor() {
return new AuthInterceptor();
}
四、化神篇:异常处理
4.1 自定义错误解码器(渡劫护盾)
public class CustomErrorDecoder implements ErrorDecoder {
@Override
public Exception decode(String methodKey, Response response) {
if (response.status() == 404) {
return new NotFoundException("资源不存在");
}
return new RuntimeException("请求失败: " + response.status());
}
}
// 注册解码器
@Bean
public ErrorDecoder errorDecoder() {
return new CustomErrorDecoder();
}
4.2 Fallback处理(降级大法)
@FeignClient(name = "product-service",
fallback = ProductClientFallback.class)
public interface ProductClient {
@GetMapping("/products/{id}")
Product getProduct(@PathVariable Long id);
}
// 降级实现
@Component
public class ProductClientFallback implements ProductClient {
@Override
public Product getProduct(Long id) {
return new Product(0L, "默认商品", 0.0); // 返回兜底数据
}
}
五、大乘篇:性能调优
5.1 启用GZIP压缩(缩地成寸)
# application.yml
feign:
compression:
request:
enabled: true
mime-types: text/xml,application/xml,application/json
min-request-size: 2048
response:
enabled: true
5.2 连接池配置(灵气循环)
feign:
httpclient:
enabled: true
max-connections: 500
max-connections-per-route: 50
六、实战心法
6.1 文件上传(乾坤大挪移)
@FeignClient(name = "file-service")
public interface FileClient {
@PostMapping(value = "/upload",
consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
String uploadFile(@RequestPart("file") MultipartFile file);
}
6.2 与Eureka集成(服务发现)
# application.yml
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
feign:
client:
config:
default:
connectTimeout: 5000
readTimeout: 30000
@FeignClient(name = "user-service") // 直接使用服务名
public interface UserClient {
// ...
}
飞升指南:最佳实践
- 接口设计:保持Feign接口与提供方API一致
- 版本控制:建议使用
@RequestMapping
指定API版本 - 日志监控:配置
Logger.Level.FULL
方便调试 - 超时设置:生产环境必须配置合理超时