3-9Feign 原生配置 · SpringCloud微服务实战 · 看云
8. Feign 原生配置
导航
在Spring Cloud 中通过使用已经封装好的Fiegn 可以很方便的调用其它服务接口,这是因为Spring Cloud 在底层做了很多工作,像集成Eureka、Ribbon、Hystrix、Sring MVC 注解等,假设你的项目不是Spring Cloud的,想用Feign 怎么办?请看本章的介绍。
原生的Feign 是不支持Spring MVC 注解的,使用的是@RequestLine注解
本节代码地址
8.1 新建项目
在这个项目里我们主要测试GET、PPST 请求,当然其他请求方式PUT、DELETE等也是支持的。
8.2 maven 配置
这里我们不引用Spring Cloud 提供的Feign包,只使用Feign自己的包,Feign的GitHub地址:https://github.com/OpenFeign/feign,有需要的可以拉源码看看。feign-gson的作用是什么,feign-gson包含了一个编码器和一个解码器,这个可以被用于JSON格式的AP,添加 GsonEncoder 以及 GsonDecoder 到你的 Feign.Builder 中I。
除了Gson 还有一下可以使用
- Jackson:添加
JacksonEncoder以及JacksonDecoder到你的Feign.Builder中 - Sax:
SaxDecoder用于解析XML,并兼容普通JVM和Android - JAXB: 添加
JAXBEncoder以及JAXBDecoder到你的Feign.Builder中
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-core</artifactId>
<version>${feign-core.version}</version>
</dependency>
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-gson</artifactId>
<version>${feign-core.version}</version>
</dependency>
</dependencies>
8.3 新建启动类
@SpringBootApplication
public class FwWithSpringCloudApplication {
public static void main(String[] args) {
SpringApplication.run(FwWithSpringCloudApplication.class, args);
}
}
8.4 新建应用配置
server:
port: 8864
8.5 新建实体类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private long id;
private String username;
private String realname;
private String email;
private String remark;
}
8.6 新建Feign请求接口
需要注意,原生的Feign 使用的是@RequestLine("GET /hello")形式的接口,里面是请求方式和接口名称,中间用空格间隔开。
public interface HelloClient {
@RequestLine("GET /hello")
String hello();
@RequestLine("GET /{id:\\d+}")
User getUserById(@Param("id") Long id);
@RequestLine("POST /getUsers")
List<User> getUsers();
}
8.7 新建控制层
用于对外测试Feign 接口,注意这里因为没用Spring Cloud 提供的Eureka注册中心,需要我们提供自己的服务地址。
@RestController
public class TestController {
@GetMapping("/hello")
public String hello(){
HelloClient hello = Feign.builder().target(HelloClient.class, "http://localhost:8764/");
return hello.hello();
}
@GetMapping("/{id:\\d+}")
public User getUserById(@PathVariable Long id){
HelloClient hello = Feign.builder().decoder(new GsonDecoder()).target(HelloClient.class, "http://localhost:8764/");
return hello.getUserById(id);
}
@PostMapping("/getUsers")
public List<User> getUsers(){
HelloClient hello = Feign.builder().decoder(new GsonDecoder()).target(HelloClient.class, "http://localhost:8764/");
return hello.getUsers();
}
}
8.8 启动项目测试
测试一: Postman 请求localhost:8864/hello
测试二: Postman 请求localhost:8864/1
测试三: Postman 请求localhost:8864/getUsers
8.9 实现原理
通过上面的测试我们可以看到验证结果是没问题的,Feign帮我们实现了服务之间的调用,实际上它是帮我们动态生成代理类,Feign使用的是JDK动态代理,生成的代理会将请求的信息封装,交给Feign.Client接口发送请求,接口的默认实现类最终会使用java.net.HttpURLConnection来发送Http请求。
很多人可能看到了decoder(new GsonDecoder()),这其实是为了解密返回的JSON字符串转成我们需要的对象,因为我们引入的Gson的包,Feign把请求的数据encode编码之后我们需要decode进行解码。



