一、概要
我们通过RestTemplate调用其它服务的API时,所需要的参数须在请求的URL中进行拼接,如果参数少的话或许我们还可以忍受,一旦有多个参数的话,这时拼接请求字符串就会效率低下,维护起来也比较麻烦
有没有跟优雅的方式来解决这样的问题,Feign
什么是Feign?
Feign是Netflix开发的声明式、模板化的HTTP客户端, Feign可以帮助我们更快捷、优雅地调用HTTP API。
简单的来说就是一个远程调用服务的框架/工具,让开发者以更少耦合更少代码更快更兼容的方法进行远程服务调用
Feign功能
- 可插拔的注解支持,包括Feign注解和JAX-RS注解;
- 支持Hystrix和它的Fallback;
- 支持可插拔的HTTP编码器和解码器;
- 支持Ribbon的负载均衡;
- 支持HTTP请求和响应的压缩。
二、基本使用
创建cloud-nacos-feign项目
添加依赖
父pom文件
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba-dependencies.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
子pom文件
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
配置文件
server:
port: 8090
spring:
application:
name: nacos-feign-example
cloud:
nacos:
discovery:
server-addr: 112.74.42.138:8848
开启注册发现
@SpringBootApplication
@EnableFeignClients
public class NacosFeignApplication {
public static void main(String[] args) {
SpringApplication.run(NacosFeignApplication.class, args);
}
}
调用服务
Service层
@FeignClient("nacos-server-provider")
public interface FeignExampleService {
@RequestMapping(method = RequestMethod.GET, value = "/")
String getData();
}
Controller层
@RestController
public class FeignExampleController {
@Resource
FeignExampleService service;
@RequestMapping("/")
public String hello() {
String s = service.getData();
return s;
}
}
三、调试测试
检查后台注册
调用服务服务接口
四、详解
@EnableFeignClients
源码
public @interface EnableFeignClients {
String[] value() default {};
String[] basePackages() default {};
Class<?>[] basePackageClasses() default {};
Class<?>[] defaultConfiguration() default {};
Class<?>[] clients() default {};
属性说明
属性 | 说明 |
---|---|
String[] value() | 包路径。比如 com.sbc.service ,会扫描这个包路径下带有 @FeignClient 注解的类并处理 |
String[] basePackages() | |
Class<?>[] basePackageClasses() | 跟 basePackages 作用一致,basePackages 是个 String 数组,而 basePackageClasses 是个 Class 数组,用于扫描这些类对应的 package |
Class<?>[] defaultConfiguration() | 默认的配置类,对于所有的 Feign Client,这些配置类里的配置都会对它们生效,可以在配置类里构造 feign.codec.Decoder , feign.codec.Encoder 或 feign.Contract 等bean; |
Class<?>[] clients() | 注解修饰的类集合,如果指定了该属性,那么扫描功能相关的属性就是失效。比如 value、basePackages 和 basePackageClasses |
@FeignClient
源码
public @interface FeignClient {
@AliasFor("name")
String value() default "";
@Deprecated
String serviceId() default "";
String contextId() default "";
@AliasFor("value")
String name() default "";
String qualifier() default "";
String url() default "";
boolean decode404() default false;
Class<?>[] configuration() default {};
Class<?> fallback() default void.class;
Class<?> fallbackFactory() default void.class;
String path() default "";
boolean primary() default true;
属性说明
属性 | 说明 |
---|---|
String value() | 提供服务的名称 |
String name() | 跟 value 属性作用一致 |
String qualifier() | 给 FeignClient 设置 @Qualifier 注解 |
String url() | 绝对路径,用于替换服务名。优先级比服务名高。 |
boolean decode404() | 默认是 false,表示对于一个 http status code 为 404 的请求是否需要进行 decode,默认不进行 decode,当成一个异常处理。设置为true之后,遇到 404 的 response 还是会解析 body |
Class<?>[] configuration() | 对于单个 FeignClient 的配置,而 @EnableFeignClients 里的 defaultConfiguration 属性是作用域全局的,针对所有的 FeignClient |
Class<?> fallback() | 表示 fallback 类,需要实现 FeignClient 对应的接口,当调用方法发生异常的时候会调用这个 Fallback 类对应的 FeignClient 接口方法 |
Class<?> fallbackFactory() | 表示生产 fallback 类的 Factory,可以实现 feign.hystrix.FallbackFactory 接口,FallbackFactory 内部会针对一个 Throwable 异常返回一个 Fallback 类进行 fallback 操作 |
String path() | 请求路径 |
boolean primary() | 默认是 true,表示当前这个 FeignClient 生成的 bean 是否是 primary。 |