Spring Cloud 声明式REST 客户端-Feign
博客专区 > jurson86 的博客 > 博客详情
Spring Cloud 声明式REST 客户端-Feign
jurson86 发表于4个月前
Spring Cloud 声明式REST 客户端-Feign
  • 发表于 4个月前
  • 阅读 1
  • 收藏 0
  • 点赞 0
  • 评论 0

腾讯云 技术升级10大核心产品年终让利>>>   

一、  什么是 Feign? 

Feign 是一种声明式、模板化的 HTTP 客户端,在 Spring Cloud 中使用 Feign,可以做到使用 HTTP
请求远程服务时能与调用本地方法一样的编码体验,开发者完全感知不到这是远程方法,更感知不到这是
个 HTTP 请求。 
Feign 的灵感来源于Retrofit、JAXRS-2.0 和 WebSocket,它使得 Java HTTP 客户端编写更方便,
旨在通过最少的资源和代码来实现和 HTTP API 的连接。 
   


二、 引入 jar  

<dependency> 
<groupId>org.springframework.cloud</groupId> 
<artifactId>spring-cloud-starter-feign</artifactId> 
</dependency> 
说明:里面的 jar 包含有spring-cloud-starter-Ribbon,是基于 Ribbon 来实现的 
 

三、  使用 

1、 加入注解 
@EnableFeignClients 
说明:这个是开启 Feign 注解 

让 Spring 扫描到@FeignClient 注解,可以设置:@EnableFeignClients(basePackages = "包名") 

@EnableCircuitBreaker
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {

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


2、 添加 IuserBiz 接口类 

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(value = "spring-cloud-provider") 
public interface IUserBiz { 
  /** 
   * @return 
   */ 
  @RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET) 
  String view(@PathVariable(value = "id") int id); 
} 

3、方法请求 

@RestController 
@RequestMapping(value = "/feign/user", method = RequestMethod.POST) 
public class FeignUserController { 
 
  @Autowired 
  private IUserBiz userBiz; 
 
  @RequestMapping(value = "/{id}", method = RequestMethod.GET) 
  public String get(@PathVariable(value = "id") int id) { 
    return userBiz.view(id); 
  } 
} 

 

四、  姿势说明 

1、 关于@PathVariable 
说明:使用@PathVariable 注解的时候,必须要定义里面的 value 或者 name 
比如:@PathVariable(value = "id")或者@PathVariable(name = "id") 
 
@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET) 
String view1(@PathVariable(name = "id") int id); 
 

2、 返回类型 
说明:可以有多种返回形式 
 
@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET) 
Map<String, Object> view2(@PathVariable(value = "id") int id); 
 
@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET) 
User view3(@PathVariable(value = "id") int id); 
 

3、 传参的问题-没有加@RequestParam 注解的情况下 
说明:请求类型将变为 post(即使指定为 get,也变为 post),将通过 Jackson 转换成json 放到请求体
中,存在一个没有带注解的参数 【存放请求body的内容】
@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET) 
User get1(@PathVariable(value = "id") int id, String name); 
 
@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET) 
User get2(@PathVariable(value = "id") int id, Map<String, Object> name); 

4、 传参的问题-有@RequestParam 注解的情况下  
说明:不指定的 value 的情况下:必须是 Map 的形式,会将其参数转换成键值的形式添加到 URL 中 ,指
定 value 的情况下:按照value 传值 
 
// 不支持该方式传值,启动出错。 
//@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET) 
//User get3(@PathVariable(value = "id") int id, @RequestParam String name); 
 
@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET) 
User get4(@PathVariable(value = "id") int id, @RequestParam Map<String, Object> name); 
 
@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET) 
User get5(@PathVariable(value = "id") int id, @RequestParam(value = "name") String name); 

 

五、高级配置说明

一、  Feign 的默认配置 


Spring Cloud Netflix 提供的默认实现类:FeignClientsConfiguration 
解码器:Decoder feignDecoder: ResponseEntityDecoder (which wraps a SpringDecoder) 
编码器:Encoder feignEncoder: SpringEncoder 
日志框架:Logger feignLogger: Slf4jLogger 
契约:Contract feignContract: SpringMvcContract 
生成器:Feign.Builder feignBuilder: HystrixFeign.Builder 
 
说明: 
解码器的作用:将 HTTP 响应数据反序列化为 Java 对象 
编码器的作用:将方法签名中方法参数对象序列化为请求参数放到 HTTP 请求中 

 

二、  自定义配置 

 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
 
import feign.Contract; 
 
// @Configuration  //配置Configuration 如被 SpringContext 扫描,否则会被@FeignClien 共用,会覆盖。 
public class RcFeignConfiguration { 
   
} 

配置 FeignClient: 
@FeignClient(value = "spring-cloud-provider", configuration = RcFeignConfiguration.class) 

 

三、  日志配置 

 

# 日志配置,默认是不打印任何的日志 
logging.level.com.hlian.education.feign.IUserBiz=debug 
 
需要在配置类里面添加以下代码 
@Bean 
    public Logger.Level feignLoggerLevel() { 
        return feign.Logger.Level.FULL; 

 
  说明:四种级别 

NONE:默认,不打印任何日志 
BASIC:打印请求方法和 URL,和请求返回状态码和执行时间。 
HEADERS:打印请求和返回的头部信息。 
FULL:打印以上的全部信息。 

 

四、  契约配置  [少用] RequestLine


1、在配置类里面添加以下代码 

@Bean 
public Contract feignContract() { 
  return new feign.Contract.Default(); 

 
2、修改 IuserBiz 类 

@RequestLine("GET /api/user/{id}") 
String view1(@Param(value = "id") int id); 

 

五、  支持压缩 


# 开启压缩 
feign.compression.request.enabled=true 
feign.compression.response.enabled=true 
# 更多配置 
feign.compression.request.mime-types=text/xml,application/xml,application/json 
feign.compression.request.min-request-size=2048 

 

六、  URL属性配置 

定义了 url 之后,vaule 为必选值,这时的 value 只是一个标识,直接跳转到对应url地址

@FeignClient(value = "hlian", url = "www.baidu.com") 
public interface IRoncooBiz { 
@RequestMapping(value = "/{url}", method = RequestMethod.GET) 
String get(@PathVariable(name = "url") String url); 
 
} 
 

 

七、  支持继承 


1、定义一个普通接口 

public interface UserService { 
 
  @RequestMapping(method = RequestMethod.GET, value = "/api/user/find/{id}") 
  User find(@PathVariable(value = "id") int id); 
} 
 

2、实现接口 

@RestController 
public class FeignApiUserController implements UserService { 
 
  protected final Logger logger = LoggerFactory.getLogger(this.getClass()); 
 
  @Override 
  public User find(@PathVariable int id) { 
    User user = new User(); 
    user.setId(id); 
    user.setName("aabbcc"); 
    user.setCreateTime(new Date()); 
    logger.info("请求接口返回:{}", user); 
    return user; 
  } 
 
} 

 

说明:springmvc 里面不支持方法参数映射的继承 
 
3、继承 
public interface IUserBiz extends UserService{ 
  // … 

 

 

 

标签: Spring Cloud
共有 人打赏支持
粉丝 0
博文 13
码字总数 120215
评论 (0)
×
jurson86
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
* 金额(元)
¥1 ¥5 ¥10 ¥20 其他金额
打赏人
留言
* 支付类型
微信扫码支付
打赏金额:
已支付成功
打赏金额: