OpenFeign的README是Feign makes writing java http clients easier,让写java http clients更容易。所以不仅是Spring cloud生态用到,只要用到Http Client的地方都可以用它。
这里我们一起感受一下Spring Cloud OpenFeign的便捷功能。
1. 简单玩法
1.1 一个简单例子
(1)服务端:
@RestController
@RequestMapping("hello")
public class HelloController implements HelloApi {
@Override
public String hello(String name) {
return "Hello, "+name+"!";
}
}
API声明:
public interface HelloApi {
@GetMapping("/hello/{name}")
String hello(@PathVariable("name") String name);
@GetMapping("/bye/{name}")
ResponseValue<String> bye(@PathVariable("name") String name);
@GetMapping(value = "/download")
byte[] download(HttpServletResponse response);
}
(2)客户端:
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
开启配置 @EnableFeignClients
,调用服务的代码:
@FeignClient(name="hello1", url = "127.0.0.1:8080", path = "hello")
public interface HelloApiExp extends HelloApi {
@GetMapping("/download")
Response download();
}
调用时的代码:
@RestController
@RequestMapping("client")
public class HelloClient {
@Autowired
private HelloApiExp helloApi;
@GetMapping("/hello/{name}")
public String hello(@PathVariable("name") String name){
return helloApi.hello(name);
}
}
浏览器访问URL:http://127.0.0.1:8080/client/hello/Mark,页面返回: Hello, Mark!
1.2 @FeignClient的简单用法
属性名称 | 属性说明 | 默认值 |
---|---|---|
name/value | 作为serviceId,bean name | |
contextId | 作为bean name,代替name/value的值 | |
qualifier | 限定词 | |
url | http的URL前缀(不包括协议名):主机名和端口号 | |
decode404 | 请求遇到404则抛出FeignExceptions | false |
path | 服务前缀,等同于ContextPath | |
primary | whether to mark the feign proxy as a primary bean | true |
2. 高级玩法
2.1 configuration配置类
通过自定义配置类统一配置Feign的各种功能属性,FeignClientsConfiguration为默认配置:
@FeignClient(name="hello1", url = "127.0.0.1:8080", configuration = FeignClientsConfiguration.class)
public interface HelloApi {
@GetMapping("/{name}")
String hello(@PathVariable("name") String name);
}
2.1.1 Decoder feignDecoder
Decoder类,将http返回的Entity字符解码(反序列化)为我们需要的实例,如自定义的POJO对象。一般使用FeignClientsConfiguration默认的feignDecoder就能满足返回String、POJO等绝大多数场景。
@Bean
@ConditionalOnMissingBean
public Decoder feignDecoder() {
return new OptionalDecoder(
new ResponseEntityDecoder(new SpringDecoder(this.messa