Maven 依赖
1 2 3 4
| <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
|
基本使用
- 在 account-api 模块中定义 API 接口 AccountApi。
1 2 3 4 5 6 7 8 9 10 11
| @FeignClient(name = "account", url = "http://localhost:8082", path = "account") public interface AccountApi {
@GetMapping("username") String getUsername(); }
|
- name 客户端名称,必要属性。如果项目使用了服务发现,name 属性需指定为微服务的名称。
- url 服务地址,一般用于调试。
- contextId 具有多个相同名称的 Feign 客户端时,需要设置该属性以区分。
- path 请求的 mapping 前缀。
- fallback 定义容错的处理类,当调用远程接口失败或超时时,会调用对应接口的容错逻辑,fallback 指定的类必须实现 @FeignClient 标记的接口。
- fallbackFactory 工厂类,用于生成 fallback 类实例,通过这个属性我们可以实现每个接口通用的容错逻辑,减少重复的代码。
- configuration Feign 配置类,可以自定义 Feign 的 Encoder、Decoder、Contract、LogLevel。
- decode404 当发生 HTTP 404 错误时,如果该属性为 true,会调用 decoder 进行解码,否则抛出 FeignException。
- 在 account-api 模块中定义 AccountController。
1 2 3 4 5 6 7 8 9 10
| @Slf4j @RequestMapping("account") @RestController public class AccountController {
@GetMapping("username") public String getUsername() { return "admin"; } }
|
注意:AccountController 不应该继承 AccountApi,因为这会导致服务的调用方和提供方紧密耦合。同时在 SpringMVC 中会有问题,因为请求参数映射是不能被继承的。
- 在 seckill-web 中启动 Feign 客户端。
1 2 3 4 5 6 7 8 9
| @EnableFeignClients(basePackages = {"account"}) @SpringBootApplication public class SeckillApplication {
public static void main(String[] args) { SpringApplication.run(SeckillApplication.class, args); }
}
|
注意: 默认会扫描启动类所在根路径下的所有使用了注解 @FeignClient 的 Feign 客户端,如果 Feign 客户端不在启动类所在根路径下,则需要设置 @EnableFeignClients 的属性 basePackages 来指定要扫描的包。
- 在 seckill-web 中使用 API 接口。
1 2 3 4 5 6 7 8 9 10 11 12 13
| @Slf4j @RequestMapping("seckill") @RestController public class SeckillController { @Autowired private AccountApi accountApi;
@GetMapping("orderId") public String getOrderId() { log.info("Username: {}", accountApi.getUsername()); return UUID.randomUUID().toString(); } }
|
服务发现支持
如果我们使用了服务发现,如 Consul 或 Eureka,那么在注解 @FeignClient 中就不需要再指定 url 属性,需要注意的是注解 @FeignClient 的 name 属性要与服务注册中心的服务名一致。