【Feign】必知必会使用

215 阅读2分钟

这是我参与更文挑战的第13天,活动详情查看:更文挑战

一、前言

Spring CloudFeign 进行了封装,使其支持 SpringMVC 标准注解和 HttpMessageConverters

Feign 可以与 EurekaRibbon 组合使用以支持负载均衡,与 Hystrix 组合使用,支持熔断回退。

cloud.spring.io/spring-clou…


使用

使用分为:

  1. 基本简单使用
  2. 上传文件
  3. 配置文件修改 URL

(1)基本使用

  1. 添加依赖
	<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
      <version>2.2.2.RELEASE</version>
    </dependency>
  1. 在启动类中添加@EnableFeignClients注解,表明启用feign客户端
@EnableFeignClients
@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
  1. 在接口上添加注解@FeignClient(name="product-service"), 表明这是一个feign客户端类接口

    其中 product-service 是 注册中心(nacoseureka)上对应的服务名。

@FeignClient("product-service")
public interface ProductClientService {
	
	@GetMapping("/api/v1/product/queryProductByIds")
	public List<Product> queryProductByIds(@RequestParam List<Integer> ids);
	
}
  1. 设置超时时间

默认readTimeout是60秒,但是默认Hystrix默认是1秒,所以超过1秒也会超时。

# 2个属性要同时设置,否则不生效,设置读取超时时间11秒
feign.client.config.default.connectTimeout=5000
feign.client.config.default.readTimeout=11000

(2)通过 Feign 上传文件

  1. 添加配置
    <dependency>
      <groupId>io.github.openfeign.form</groupId>
      <artifactId>feign-form</artifactId>
      <version>3.8.0</version>
    </dependency>
    <dependency>
      <groupId>io.github.openfeign.form</groupId>
      <artifactId>feign-form-spring</artifactId>
      <version>3.8.0</version>
    </dependency>
    <dependency>
      <groupId>commons-fileupload</groupId>
      <artifactId>commons-fileupload</artifactId>
      <version>1.3.3</version>
    </dependency>
    <dependency>
      <groupId>org.apache.commons</groupId>
      <artifactId>commons-pool2</artifactId>
    </dependency>
  1. 定义 Feign 配置
@Configuration
public class MultipartSupportConfig {

    @Autowired
    private ObjectFactory<HttpMessageConverters> messageConverters;

    @Bean
    public Encoder feignFormEncoder() {
        return new SpringFormEncoder(new SpringEncoder(messageConverters));
    }
}
  1. 使用
import cn.percent.dolphin.oceanfile.common.Response;
import cn.percent.dolphin.oceanfile.config.MultipartSupportConfig;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
import org.springframework.web.multipart.MultipartFile;

@FeignClient(value = "oss", configuration = MultipartSupportConfig.class)
public interface OssClient {

    /**
     * 上传文件
     *
     * @param file 文件
     * @return 路径
     */
    @PostMapping(value = "/api/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    Response<String> uploadFile(@RequestPart(value = "file") MultipartFile file);

    /**
     * 下传文件
     *
     * @param path 路径
     * @return 字节流
     */
    @GetMapping(value = "/api/download")
    feign.Response downloadFile(@RequestParam(value = "path") String path);
}
  1. 上步骤的 Response
public class Response<T> implements Serializable {
    /**
     * 状态码
     */
    private Integer code;
    /**
     * 消息
     */
    private String msg;
    /**
     * 数据
     */
    private T data;

    ......
}

(3)根据配置文件修改 URL

  1. 尝试根据 配置文件 更改 URL
@FeignClient(name = "test", url="http://xxxx")
  1. 修改
@FeignClient(url = "${feign.client.url.TestUrl}")

application.yml 如下:

feign:
  client:
    url:
      TestUrl: http://dev:dev



二、添加 Hystrix

  1. 依赖
    <!-- 已经带有 hystrix -->
	<dependency>
      <groupId>org.springframework.cloud</groupId>
      <artifactId>spring-cloud-starter-openfeign</artifactId>
    </dependency>
  1. 实现
@FeignClient("product-service",fallback = ProductFeignFallback.class)
public interface ProductClientService {
	
	@GetMapping("/api/v1/product/queryProductByIds")
	public List<Product> queryProductByIds(@RequestParam List<Integer> ids);
	
}

服务降级处理:

import com.springcloud.product.feign.PriceFeign;
import lombok.extern.slf4j.Slf4j;

/**
 *价格服务降级处理
 */
@Slf4j
public class ProductFeignFallback implements ProductClientService {
    @Override
    public List<Product> queryProductByIds( List<Integer> ids) {
        log.info("执行降级逻辑开始...");
        return Collections.emptyList();
    }
}