Spring Cloud(六)Feign实现声明式REST调用

Feign简介

Feign是Netflix开发的声明式、模板化的HTTP客户端。Feign可帮助我们更加便捷、优雅地调用HTTP API。
在Spring Cloud中,使用Feign非常简单—–创建一个接口,并在类上添加一些注解,代码就完成了。
Spring Cloud对Feign进行了增强,使Feign支持了Spring MVC注解,并整合了Eureka和Ribbon,从而让Feign的使用更加方便。

使用Feign

1:新建Spring Boot项目EurekaServer,添加依赖Eureka Server
2:启动类

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {

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

3:配置文件application.yml

server:
  port: 8761                  
eureka:
  client:
    registerWithEureka: false    #是否将自己注册到Eureka Server,默认为True。由于当前应用就是Eureka Server,故false
    fetchRegistry: false         #是否从Eureka Server获取注册信息,默认True。因为这是一个单节点的Eureka Server,不需要同步其他的Eureka Server节点,故false
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/

4:新建Spring Boot项目EurekaClient,添加依赖Eureka Client(已经包含了Web)
这里写图片描述
5:启动类

@EnableDiscoveryClient
@SpringBootApplication
public class EurekaClientApplication {

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

6:MyController

@RestController
public class MyController {
    @RequestMapping("/eureka/test")   //等会测试的时候访问它
    public String test() 
    {
        return "Hello Feign";
    }
}

7:配置文件application.yml

server:
  port: 8003
spring:
  application:
    name: EurekaClinet
eureka:
  client:
    serviceUrl:
      defaultZone: http://localhost:8761/eureka/
  instance:
    prefer-ip-address: true 

8:新建Spring Boot项目ServerFeign,添加依赖Eureka Client(已经包含了Web)、Feign
9:启动类

@EnableDiscoveryClient
@EnableFeignClients
@SpringBootApplication
public class ServerFeignApplication {

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

10:Feign接口

@FeignClient(name = "EurekaClinet")
public interface UserFeignClient {    //不需要实现
  @RequestMapping(value = "/eureka/test", method = RequestMethod.GET)
  public String test();
}

11:MyController

@RestController
public class MyController{
  @Autowired
  private UserFeignClient userFeignClient;

  @GetMapping("/testFeign")
  public String testFeign() {     
    return this.userFeignClient.test();  //会去访问EurekaClinet的/eureka/test,前面已经定义过了
  }

  private static final Logger LOGGER = LoggerFactory.getLogger(MyController.class);
  @Autowired
  private LoadBalancerClient loadBalancerClient;
  @GetMapping("/log-user-instance")
  public void logUserInstance() {
    ServiceInstance serviceInstance = this.loadBalancerClient.choose("EurekaClinet");
    // 打印当前选择的是哪个节点
    MyController.LOGGER.info("{}:{}:{}", serviceInstance.getServiceId(), serviceInstance.getHost(), serviceInstance.getPort());
  }
}

12:项目结构
这里写图片描述
13:运行测试
启动项目EurekaServer
启动项目EurekaClient(以8003端口启动)
启动项目EurekaClient(以8004端口启动)
启动项目ServerFeign
访问:http://localhost:8011/testFeign
这里写图片描述
这里写图片描述
可以看到,不但实现了声明式REST API调用,同时还实现了客户端的负载均衡!

自定义Feign配置

在Spring Cloud中Feign默认使用的契约是SpringMvcContract,因此它可以使用Spring MVC的注解。下面来自定义Feign的配置,让它使用Feign自带的注解进行工作:
1:项目ServerFeign添加Feign的配置类

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

2:修改Feign接口

@FeignClient(name = "EurekaClinet",configuration=FeignConfiguration.class)
public interface UserFeignClient {
  @RequestLine("GET /eureka/test")
  public String test();

}

3:项目结构
这里写图片描述
4:运行测试
结果与上面的一致!

Feign对压缩的支持

一些场景下,可能需要对请求或响应进行压缩,此时可使用以下属性启用Feign的压缩功能:

feign.compression.request.enabled=true
feign.compression.response.enabled=true 

对于请求的压缩,Feign还提供了更为详细的设置:

feign.compression.request.enabled=true
feign.compression.request.mime-types=text/xml,application/xml,application/json//支持的媒体类型,默认它们三
 feign.compression.request.min-request-size=2048    //设置请求的最小阈值,默认2048   

该特性在Spring Cloud Camden SR4不生效。不知道以后会不会解决!

Feign的日志

Feign对日志的处理非常灵活,可为每个Feign客户端指定日志记录策略,每个Feign客户端都会创建一个logger。默认情况下,logger的名称是Feign接口的完整类名。需要注意的是,Feign的日志打印只会对DEBUG级别做出响应。
我们可为每个Feign客户端配置各自的Logging .Level对象,告诉Feign记录哪些日志。Logging .Level的值有以下选择:
这里写图片描述
1:修改ServerFeign配置类

@Configuration
public class FeignConfiguration {   
      @Bean
      Logger.Level feignLoggerLevel() {
        return Logger.Level.FULL; //将日志级别设置为FULL
      }
}

2:在Feign接口,指定配置类

@FeignClient(name = "EurekaClinet",configuration=FeignConfiguration.class)
public interface UserFeignClient {
    @RequestMapping(value = "/eureka/test", method = RequestMethod.GET)
      public String test();
}

3:在application.yml添加

logging:
  level:  //ServerFeign.feign.UserFeignClient是你的Feign接口位置
    ServerFeign.feign.UserFeignClient: DEBUG # 将Feign接口的日志级别设置成DEBUG,因为Feign的Logger.Level只对DEBUG作出响应。

4:运行测试
启动项目EurekaServer
启动项目EurekaClient
启动项目ServerFeign
访问:http://localhost:8011/testFeign
这里写图片描述
将日志Feign的日志级别改为BASIC,重启项目访问:http://localhost:8011/testFeign
这里写图片描述
此时,只打印了请求方法、请求的URL和相应的状态码和响应的时间!

使用Feign构造多参数请求

GET请求多参数的URL:
假设请求http://localhost:8011/testFeign/get?id=5&username=yangdong
Feign接口

@FeignClient(name = "EurekaClinet",configuration=FeignConfiguration.class)
public interface UserFeignClient { 
    @RequestMapping(value = "/eureka/test", method = RequestMethod.GET)
    public String testGet(@RequestParam("id") Long id,@RequestParam("username") String username);   
}

URL有几个参数,Feign接口中的方法就有几个参数!!!
ServerFeign控制器MyController

  @GetMapping("/testFeign/get")
  public String testGet(@RequestParam("id") Long id,@RequestParam("username") String username) {
    return this.userFeignClient.testGet(id, username);
  }

EurekaClient控制器MyController

@RestController
public class MyController {     
    @RequestMapping("/eureka/test")
    public String test(@RequestParam("id") Long id,@RequestParam("username") String username) 
    {       
        return "Hello"+id+username;
    }
}

运行测试
访问:http://localhost:8011/testFeign/get?id=5&username=yangdong
访问流程为:ServerFeign控制器MyController的testGet方法,获取到id参数与username参数。执行Feign接口的testGet方法,去访问EurekaClient控制器MyController的test方法。
这里写图片描述

参考书籍:Spring Cloud与Docker微服务架构实战
以上只是学习所做的笔记,以供日后参考!!!

猜你喜欢

转载自blog.csdn.net/z1790424577/article/details/81197747