1.概念
OpenFeign是Netflix 开发的声明式、模板化的HTTP请求客户端。可以更加便捷、优雅地调用http api。
OpenFeign会根据带有注解的函数信息构建出网络请求的模板,在发送网络请求之前,OpenFeign会将函数的参数值设置到这些请求模板中。
feign主要是构建微服务消费端。只要使用OpenFeign提供的注解修饰定义网络请求的接口类,就可以使用该接口的实例发送RESTful的网络请求。还可以集成Ribbon和Hystrix,提供负载均衡和断路器。
英文表意为“假装,伪装,变形”, 是一个 Http 请求调用的轻量级框架,可以以 Java 接口注解的方式调用 Http 请求,而不用像 Java 中通过封装 HTTP 请求报文的方式直接调用。通过处理注解,将请求模板化,当实际调用的时候,传入参数,根据参数再应用到请求上,进而转化成真正的请求,这种请求相对而言比较直观。Feign 封装 了HTTP 调用流程,面向接口编程。
2.使用demo
1.创建接口 2.添加注解
pom.xml
<!-- 引入feign依赖 ,用来实现接口伪装 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
添加接口,注解。
一般一个服务提供者,写一个interface
//此处由于结合了eureka,所以name是 虚拟主机名,默认服务名,请求时 会将它解析成注册表中的服务。
//不结合eureka,就是自定义一个client名字。就用url属性指定 服务器列表。url=“http://ip:port/”
//此时的name作用就是创建负载均衡器。
//也可以添加@RequestMapping
@FeignClient(name = "service-valuation")
public interface ServiceForecast {
@RequestMapping(value = "/forecast/single",method = RequestMethod.POST)
public ResponseResult<ForecastResponse> forecast(@RequestBody ForecastRequest forecastRequest);
}
启动类添加
@EnableFeignClients
就像是一个开关,只有使用了该注解,OpenFeign相关的组件和配置机制才会生效。
还可以对OpenFeign相关组件进行自定义配置
调用
@Autowired
private ServiceForecast serviceForecast;
@PostMapping("/forecast")
public ResponseResult<ForecastResponse> forecast(@RequestBody ForecastRequest forecastRequest) {
ResponseResult<ForecastResponse> result = serviceForecast.forecast(forecastRequest);
return ResponseResult.success(result.getData());
}
PS:调用此方法:会向service-valuation服务的接口:/forecast/single 发送请求。
3.自定义feign配置
通过权限的例子,学习feign的自定义配置
服务提供者service-valuation添加权限功能
开放权限:
<!-- 安全认证 -->
<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
有如下两种方式:
- 自定义配置类。
配置类:
public class FeignAuthConfiguration {
@Bean
public BasicAuthRequestInterceptor basicAuthRequestInterceptor() {
return new BasicAuthRequestInterceptor("root", "root");
}
}
在feign上加配置
@FeignClient(name = "service-valuation",configuration = FeignAuthConfiguration.class)
2. 增加拦截器。
定义拦截器
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-valuation:
request-interceptors:
- com.online.taxi.passenger.feign.interceptor.MyBasicAuthRequestInterceptor
使用任意一种,即可通过权限访问。
4.Feign日志
feign:
client:
config:
service-valuation:
logger-level: basic
//上面有4种日志类型
none:不记录任何日志,默认值
basic:仅记录请求方法,url,响应状态码,执行时间。
headers:在basic基础上,记录header信息
full:记录请求和响应的header,body,元数据。
//上面的logger-level只对下面的 debug级别日志做出响应。
logging:
level:
com.online.taxi.passenger.feign.ServiceForecast: debug
5.Feign构造多参数请求
1. GET多参数请求
- 接口方法种使用 方法(@RequestParam("id") long id)。
- 用map,方法(@RequestParam Map<String , Object> map)。
2.POST多参数请求
- 用bean。方法(@RequestBody User bean)
6.原理
- 主程序入口添加@EnableFeignClients注解开启对Feign Client扫描加载处理。根据Feign Client的开发规范,定义接口并加@FeignClient注解。
- 当程序启动时,会进行包扫描,扫描所有@FeignClient注解的类,并将这些信息注入Spring IoC容器中。当定义的Feign接口中的方法被调用时,通过JDK的代理方式,来生成具体的RequestTemplate。当生成代理时,Feign会为每个接口方法创建一个RequestTemplate对象,该对象封装了HTTP请求需要的全部信息,如请求参数名、请求方法等信息都在这个过程中确定。
- 然后由RequestTemplate生成Request,然后把这个Request交给client处理,这里指的Client可以是JDK原生的URLConnection、Apache的Http Client,也可以是Okhttp。最后Client被封装到LoadBalanceClient类,这个类结合Ribbon负载均衡发起服务之间的调用。