SpringCloud微服务之四:Feign实现声明式REST调用(一)
文章目录
- SpringCloud微服务之四:Feign实现声明式REST调用(一)
- 前言
- 一、Feign简介
- 二、服务消费者整合Feign
- 1.添加依赖
- 2.创建Feign接口
- 3.启动类上添加启动功能注解
- 4、调用测试
- 三、自定义Feign配置
- 1.Feign自带的一些注解
- 2.Feign自定义拦截器
- 3、使用属性自定义Feign配置
前言
Spring Cloud OpenFeign 是声明式的服务调用工具,它整合了Ribbon和Hystrix,拥有负载均衡和服务容错功能,本文将对其用法进行详细介绍。
一、Feign简介
Feign是Netflix开发的声明式的服务调用工具,我们只需创建一个接口并用注解的方式来配置它,就可以实现对某个服务接口的调用,简化了直接使用RestTemplate来调用服务接口的开发量。Feign具备可插拔的注解支持,同时支持Feign注解、JAX-RS注解及SpringMvc注解。当使用Feign时,Spring Cloud集成了Ribbon和Eureka以提供负载均衡的服务调用及基于Hystrix的服务容错保护功能。
二、服务消费者整合Feign
1.添加依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2.创建Feign接口
package com.yangxf.cloud.study.user.feign;
import com.yangxf.cloud.study.user.entity.User;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
@FeignClient(name = "microservice-provider-user")
public interface UserFeignClient {
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public User findById(@PathVariable("id") Long id);
}
3.启动类上添加启动功能注解
@EnableDiscoveryClient
@SpringBootApplication
@EnableFeignClients
public class ConsumerMovieApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerMovieApplication.class, args);
}
}
- 这是使用啦Eureka注册表,microservice-provider-user是已经注册的服务名,如不想使用Eureka,
- 也可以通过microservice-provider-user.ribbon.listOfServers属性配置服务集合,逗号分隔,如microservice-provider-user.ribbon.listOfServers=localhost:8000,localhost:8001完成服务地址配置;
- 也可以通过@FeignClient(name = “microservice-provider-user”,url=“http://localhost:8000/”)注解配置
4、调用测试
package com.yangxf.cloud.study.user.controller;
import com.yangxf.cloud.study.user.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.yangxf.cloud.study.user.feign.UserFeignClient;
@RestController
public class MovieController {
@Autowired
private UserFeignClient userFeignClient;
@GetMapping("/user/{id}")
public User findById(@PathVariable Long id) {
return this.userFeignClient.findById(id);
}
}
多次访问http://localhost:8010/user/1,可以看到多个microservice-provider-user的控制台都有日志数据;
总结:使用Feign不但实现了声明式的REST API的调用,同时实现了客户端侧的负载均衡。
三、自定义Feign配置
- 很多场景下,我们需要自定义Feign的配置,例如配置,日志级别、定义拦截器等。
- Spring Cloud Edgware版本后允许通过java代码和属性配置。
- Spring Cloud中,默认配置类是FeignClientsConfiguration,该类定义了Feign的默认使用的编码器,解码器,所使用的契约等信息;
- Spring Cloud允许通过@FeignClient中configuration属性自定义Feign的配置,优先级高于默认配置类,自定义的配置类不要放在启动项扫描范围之内。
1.Feign自带的一些注解
// 1、正常使用、正常书写
@Headers({"Accept:*/*", "Accept-Language: zh-cn"})
@RequestLine("GET /feign/demo1?name={name}")
String testRequestLine(@Param("name") String name);
// 2、GET后不止一个空格,有多个空格
@RequestLine("GET /feign/demo1?name={name}")
String testRequestLine2(@Param("name") String name);
// 3、使用Map一次性传递多个查询参数,使用注解为@QueryMap
@RequestLine("GET /feign/demo1")
String testRequestLine3(@QueryMap Map<String, Object> params);
// 4、方法参数上不使用任何注解
@RequestLine("GET /feign/demo1")
String testRequestLine4(String name);
// 5、方法上标注有@Body注解,然后把方法参数传递给它
@RequestLine("GET /feign/demo1")
@Body("{name}")
String testRequestLine5(@Param("name") String name);
2.Feign自定义拦截器
比如,一些一些借口需要进行基于HTTP BASIC的认证后才能调用,配置如下:
package com.yangxf.cloud.config;
import feign.auth.BasicAuthRequestInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import feign.Contract;
/**
* 该类为Feign的配置类
* 注意:该不应该在主应用程序上下文的@ComponentScan中。
* @author linwd
*/
@Configuration
public class FeignConfiguration {
/**
* 将契约改为feign原生的默认契约。这样就可以使用feign自带的注解了。
* @return 默认的feign契约
*/
@Bean
public Contract feignContract() {
return new feign.Contract.Default();
}
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor(){
return new BasicAuthRequestInterceptor("user","password1");
}
}
3、使用属性自定义Feign配置
属性配置优先级高于java配置
feign:
client:
config:
default: #默认全局配置
conectTimeOut: 5000 #相当于Request.Options
readTimeOut: 5000 #相当于Request.Options
loggerLevel: basic
oneFeignName: #feign服务名
conectTimeOut: 5000 #相当于Request.Options
readTimeOut: 5000 #相当于Request.Options
loggerLevel: full #配置日志级别,相当于代码配置中Logger
errorDecoder: com.yangxf.SimpleErrorDecoder #错误解码器,相当于代码中ErrorDecoder
retryer: com.yangxf.SimpleRetryer #配置重试,相当于代码中Retryer
requestInterceptors: #拦截器
- com.yangxf.OneRequestInterceptor
- com.yangxf.TwoRequestInterceptor
decode404: false