一、什么是Feign
Feign是Netflix开发的一套声明式、模板话的http请求客户端,更便捷优雅的迪用API。
会根据带有注解的函数信息构建网络请求模板,在请求发送之前,将函数的参数值设置到请求模板中。
是一个http请求的轻量级框架,封装了http调用流程,面向接口编程,可以以接口注解的方式调用http请求,而不用向java中封装请求报文的方式直接调用,通过处理注解,将请求模板化,当实际调用的时候传入参数,根据参数再应用到请求上,进而转化成真正的请求。
可以集成ribbon和hystrix,提供负载均衡和断路器机制。
二、Feign和OpenFeign的关系
Feign有一套自己独立的主角,不支持SpringMVC的注解。所以有了OpenFeign,它是SpringCloud在Feign的基础上支持了SpringMVC的注解,如@RequestMapping等。
OpenFeign的@FeignClient注解可以解析@RequestMapping注解下的一些接口,并通过动态代理的方式产生实现类,实现类中负载均衡调用其他服务。
三、配置使用
1、依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2、当前服务需要连接Eureka服务器
3、启动类添加@EnableFeignClients注解
4、Feign默认所有带参数的请求都是Post,想要使用指定的提交方式需引入依赖
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-httpclient</artifactId>
</dependency>
四、配置权限
1、feign的默认配置类是:org.springframework.cloud.openfeign.FeignClientsConfiguration。默认定义了feign使用的编码器,解码器等。
允许使用@FeignClient的configuration的属性自定义Feign配置。自定义的配置优先级高于上面的FeignClientsConfiguration。
开放权限:
<!-- 安全认证 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
@Configuration
@EnableWebSecurity
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(HttpSecurity http) throws Exception {
// 关闭csrf
http.csrf().disable();
// 表示所有的访问都必须认证,认证处理后才可以正常进行
http.httpBasic().and().authorizeRequests().anyRequest().fullyAuthenticated();
// 所有的rest服务一定要设置为无状态,以提升操作效率和性能
http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
}
}
spring:
security:
user:
name: root
password: root
2、自定义配置配
配置类:
public class FeignAuthConfiguration {
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("root", "root");
}
}
在feign上加配置
@FeignClient(name = "service-auth",configuration = FeignAuthConfiguration.class)
//如果在配置类上添加了@Configuration注解,并且该类在@ComponentScan所扫描的包中,那么该类中的配置信息就会被所有的@FeignClient共享。最佳实践是:不指定@Configuration注解(或者指定configuration,用注解忽略),而是手动:
//@FeignClient(name = "service-auth",configuration = FeignAuthConfiguration.class)
3、拦截器
import feign.RequestInterceptor;
import feign.RequestTemplate;
public class MyBasicAuthRequestInterceptor implements RequestInterceptor {
@Override
public void apply(RequestTemplate template) {
// TODO Auto-generated method stub
template.header("Authorization", "Basic cm9vdDpyb290");
}
}
feign:
client:
config:
service-auth:
request-interceptors:
- com.xinay.feign.interceptor.MyBasicAuthRequestInterceptor
# 对指定服务进行配置
feign:
client:
config:
service-auth:
connect-timeout: 5000
read-timeout: 5000
logger-level: full
# 通用配置
feign:
client:
config:
default:
connect-timeout: 5000
read-timeout: 5000
logger-level: full
# 属性配置默认比java代码配置优先级高 可以通过此项配置调整
feign:
client:
default-to-properties: false
五、原理
1、主程序入口添加@EnableFeignClients注解开启对Feign Client扫描加载处理。
2、当程序启动时,会进行包扫描,扫描所有添加@FeignClient注解的类,将这些信息注入Spring IOC容器中,当定义的Feign接口中的方法被调用时,通过JDK代理为每一个方法生成具体的RequestTemplate对象,这个对象封装了http请求需要的全部信息,如请求参数名、请求方法等信息都在这个过程中确定。
3、然后由RequestTemplate生成Request,然后把这个Request交给Client(JDK原生的URLConnection/Apache的HttpClient/Okhttp)处理,最后Client被封装到LoadBalanceClient类,结合ribbon负载均衡发起服务之前的调用。
六、压缩
#服务端开启压缩
server.compression.enabled=true
#调用方配置
#配置请求GZIP压缩
feign.compression.request.enabled=true
#配置响应GZIP压缩
feign.compression.response.enabled=true
#单位是B
feign.compression.request.min-request-size=100