1. Feign 简介
- Feign是在RestTemplate基础上封装的,使用注解的方式来声明一组与服务提供者Rest接口所对应的本地Java API接口方法。
- Feign将远程Rest接口抽象成一个声明式的FeignClient(Java API)客户端,并且负责完成FeignClient客户端和服务提供方的Rest接口绑定。
- Feign 使用了动态代理,使用@FeignClient调用接口的本质就是调用Feign创建的动态代理,然后根据接口上的@RequestMapping等注解,来动态构造出要请求的服务的地址并对这个地址发起请求、解析响应。
- Feign具备可插拔的注解支持,包括Feign注解和JAX-RS注解。同时,对于Feign自身的一些主要组件,比如编码器和解码器等,也以可插拔的方式提供,在有需求时方便扩张和替换它们。
- 在 Spring Cloud 中使用 Feign,可以做到使用 HTTP 请求访问远程服务,就像调用本地方法一样的,开发者完全感知不到这是在调用远程方法,更感知不到在访问 HTTP 请求。接下来介绍一下 Feign 的特性,具体如下:
- 可插拔的注解支持,包括 Feign 注解和AX-RS注解。
- 支持可插拔的 HTTP 编码器和解码器。
- 支持 Hystrix 和它的 Fallback。
- 支持 Ribbon 的负载均衡。
- 支持 HTTP 请求和响应的压缩。
6.它整合了 Ribbon 和 Hystrix,从而不需要开发者针对 Feign 对其进行整合。Feign 还提供了 HTTP 请求的模板,通过编写简单的接口和注解,就可以定义好 HTTP 请求的参数、格式、地址等信息。Feign 会完全代理 HTTP 的请求,在使用过程中我们只需要依赖注入 Bean,然后调用对应的方法传递参数即可。
2. 使用步骤
- 使用Feign的第1步是在项目的pom.xml文件中添加Feign依赖:
<!--添加Feign依赖--> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-openfeign</artifactId> </dependency>
使用Feign的第2步是在主函数的类上添加@EnableFeignClient,在客户端启动Feign:
package com.crazymaker.springcloud.user.info.start; ... //启动Feign @EnableFeignClients(basePackages = { "com.crazymaker.springcloud.seckill.remote.client"}, defaultConfiguration = {TokenFeignConfiguration.class} ) public class UserCloudApplication { public static void main(String[] args) { SpringApplication.run(UserCloudApplication.class, args); } }
3.使用Feign的第3步是编写声明式接口。这一步将远程服务抽象成一个声明式的FeignClient客户端,示例如下:
package com.crazymaker.springcloud.seckill.remote.client; ... /** *@description:远程服务的本地声明式接口 */ @FeignClient(value = "seckill-provider", path = "/api/demo/") public interface DemoClient { /** *测试远程调用 *@return hello */ @GetMapping("/hello/v1") Result<JSONObject> hello(); /** *非常简单的一个回显接口,主要用于远程调用 *@return echo回显消息 */ @RequestMapping(value = "/echo/{word}/v1", method = RequestMethod.GET) Result<JSONObject> echo( @PathVariable(value = "word") String word); }
- 在上面接口的@FeignClient注解配置中,使用value指定了需要绑定的服务,使用path指定了接口的URL前缀。然后使用@GetMapping和@RequestMapping两个方法级别的注解分别声明了两个远程调用接口。
- 使用Feign的第4步是调用声明式接口。
package com.crazymaker.springcloud.user.info.controller; ... @Api(value = "基础学习DEMO", tags = {"基础学习DEMO"}) @RestController @RequestMapping("/api/demo") public class DemoController { //注入 @FeignClient注解所配置的客户端实例 @Resource DemoClient demoClient; @GetMapping("/say/hello/v1") @ApiOperation(value = "Feign远程调用") public Result<JSONObject> hello() { Result<JSONObject> result = demoClient.hello(); JSONObject data = new JSONObject(); data.put("remote", result); return Result.success(data).setMsg("操作成功"); } }