使用Feign实现声明式Rest调用

一,前言
使用RestTemplate实现Rest API调用时,我们是使用拼接字符串的方式拼接URL的,URL中如果有参数而且参数比较多,这就变得难以维护。

二,Feign简介
Feign是Netflix开发的声明式、模板化的Http客户端,其灵感来自Retrofit、JAXRS-2.0以及WebSocket。Feign可以更便捷、优雅的调用Http API
在Spring Cloud中使用Feign非常简单,创建一个接口,并在接口上添加注解就完成了。
Feign支持多种注解,Feign自带的或JAX-RS注解等。
Spring Cloud对Feign进行了增强,使Feign支持了SpringMVC注解,并整合了Ribbon和Eureka,从而让Feign的使用更加方便。

三,为消费者整合Feign
1,添加Feign依赖


org.springframework.cloud
spring-cloud-starter-feign
1.4.7.RELEASE

2,创建Feign接口,并添加@FeignClient注解
/**

  • Feign客户端接口

  • @author yebin

  • @date 2020/12/8 10:44

  • @since 1.0.1
    */
    @FeignClient(name = "movie-provider")
    public interface UserFeignClient {

    @RequestMapping(value = "/{id}",method = RequestMethod.GET)
    public User findById(@PathVariable("id") Long id);
    }

3,修改Controller及启动类
@RestController
@Slf4j
public class UserController {
@Autowired
private RestTemplate restTemplate;
@Autowired
private DiscoveryClient discoveryClient;
@Autowired //注入负载均衡客户端
private LoadBalancerClient loadBalancerClient;
@Autowired
private UserFeignClient userFeignClient;

//feign方式调用
@GetMapping("/user/feign/{id}")
public User findByIdFeign(@PathVariable Long id) {
    return this.userFeignClient.findById(id);
}

//restTemplate方式调用
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
    return this.restTemplate.getForObject("http://movie-provider:8091/" + id, User.class);
}

@GetMapping("/user/list")
public List findAll() {
    return restTemplate.getForObject("http://movie-provider:8091/list", List.class);
}

/**
 * 获取提供者元数据信息
 * @return
 */
@GetMapping("/provider/instance")
public List getServiceInstance(){
    return  discoveryClient.getInstances("movie-provider");
}

/**
 * 打印当前选择的是哪个节点
 * 注意:
 * 不能将restTemplate.getForObject()与loadBalancerClient.choose()写在一个方法中,两者会引起冲突,因为代码中restTemplate实际上
 * 是一个Ribbon客户端,本身已经包含了choose行为。
 */
@GetMapping("/print-instance")
public void printInstance(){
    ServiceInstance serviceInstance = loadBalancerClient.choose("movie-provider");
    log.info("serviceId--->{},host--->{},port--->{}",serviceInstance.getServiceId(),serviceInstance.getHost(),serviceInstance.getPort());
}

}

/**

  • 1,@EnableDiscoveryClient 声明这是一个Eureka Client,此处可用@EnableEurekaClient代替。

  • 2,spring cloud 中服务发现组件有多种,如:Zookeeper,Consul等,@EnableDiscoveryClient为各种组件提供了支持。

  • 3,@EnableDiscoveryClient是spring-cloud-commons项目的注解,是一个高度的抽象。

  • 4,@EnableEurekaClient表明是Eureka 的Client,该注解是是spring-cloud-netflix项目的,只能与Eureka一起工作。
    */
    @EnableDiscoveryClient
    //@EnableEurekaClient
    @SpringBootApplication
    @EnableFeignClients //启用Feign客户端
    public class MovieConsumerFeignApplication {

    @Bean
    @LoadBalanced
    public RestTemplate restTemplate(){
    return new RestTemplate();
    }

    public static void main(String[] args) {
    SpringApplication.run(MovieConsumerFeignApplication.class, args);
    }

}

4,自定义Feign配置


image.png

image.png

/**

  • Feign自定义配置类

  • Feign配置类不应放在与启动类同一个包下,否则该类中的配置信息就会被所有@FeignClient共享,或者显式指定

  • @ComponetScan不扫描@Configuration所在的包

  • @author yebin

  • @date 2020/12/8 11:06

  • @since 1.0.1
    */
    @Configuration
    public class FeignConfiguration {

    //将契约改为feign原生的契约,这样可以使用feign自带的注解了。
    @Bean
    public Contract feignContract(){
    return new feign.Contract.Default();
    }
    }

5,Feign对继承的支持
Feign支持继承,可将一些公共操作抽到父接口中,以简化Feign的操作。


image.png

6,Feign对压缩的支持
一些场景下需要对请求或响应进行压缩,此时可以使用以下属性来启用Feign的压缩功能。
feign.compression.request.enable=true
feign.compression.response.enable=true
对于请求的压缩,Feign还可以更为详细的设置:
feign.compression.request.enable=true

支持的媒体类型

feign.compression.request.mime-types=text/xml,application/xml,application/json

请求的最小阈值,默认是2048

feign.compression.request.min-request-size=2048

7,Feign的日志
Feign对日志处理非常灵活,可为每个Feign客户端指定日志记录策略,每个Feign客户端都会记录一个logger。默认情况下,logger的名称是Feign接口的完事类名,需要注意的是Feign的日志只会对DEBUG级别日志做出响应。


image.png
7.1 Feign的配置类

/**

  • Feign自定义配置类
  • Feign配置类不应放在与启动类同一个包下,否则该类中的配置信息就会被所有@FeignClient共享,或者显式指定
  • @ComponetScan不扫描@Configuration所在的包
  • @author yebin
  • @date 2020/12/8 11:06
  • @since 1.0.1
    */
    @Configuration
    public class FeignConfiguration {
    //Feign日志
    @Bean
    Logger.Level feignLoggerLevel(){
    return Logger.Level.FULL;
    }
    }

8,使用Feign构造多请求的参数
Spring Cloud为Feign添加了Spring MVC注解的支持,可以使用参照Spring MVC注解的方式来构造多请求参数
GET请求:
8.1
@Configuration
public class FeignConfiguration {
@GetMapping("/get")
public User get(@RequestParam("id") Long id,@RequestParam("username") String username){
...
}
}
POST请求:
@RestController
@Slf4j
public class UserController {
@PostMapping("/post")
public User post(@RequestBody User user){
return null;
}

你可能感兴趣的:(使用Feign实现声明式Rest调用)