一、全局配置自定义
1、代码配置
- 方式一:让父子上下文ComponentScan重叠(强烈不建议使用)
@Configuration public class StockFeignConfiguration { /** * 日志级别 * 通过源码可以看到日志等级有 4 种,分别是: * NONE:不输出日志。 * BASIC:只输出请求方法的 URL 和响应的状态码以及接口执行的时间。 * HEADERS:将 BASIC 信息和请求头信息输出。 * FULL:输出完整的请求信息。 */ @Bean public Logger.Level level(){ return Logger.Level.FULL; } } 复制代码
- 方式二【唯一正确的途径】: EnableFeignClients(defaultConfiguration=xxx.class)
2、属性配置
logging: level: com.nx: debug feign: client: config: default: loggerLevel: full 复制代码
二、 支持的配置项
1、契约配置
Spring Cloud 在 Feign 的基础上做了扩展,可以让 Feign 支持 Spring MVC 的注解来调用。原生的 Feign 是不支持 Spring MVC 注解的,如果你想在 Spring Cloud 中使用原生的注解方式来定义客户端也是 可以的,通过配置契约来改变这个配置,Spring Cloud 中默认的是 SpringMvcContract。
1.1代码方式
/** * 修改契约配置,这里仅仅支持Feign原生注解 * 这里是一个扩展点,如果我们想支持其他的注解,可以更改Contract的实现类。 * @return */ @Bean public Contract feignContract(){ return new Contract.Default(); } 复制代码
注意:这里修改了契约配置之后,我们就只能用Fegin的原生注解
1.2 属性方式
2、编解码
Feign 中提供了自定义的编码解码器设置,同时也提供了多种编码器的实现,比如 Gson、Jaxb、Jackson。 我们可以用不同的编码解码器来处理数据的传输。。
扩展点:Encoder & Decoder
默认我们使用:SpringEncoder和SpringDecoder
package feign.codec; public interface Encoder { void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException; } 复制代码
package feign.codec; public interface Decoder { Object decode(Response response, Type type) throws IOException, DecodeException, FeignException; } 复制代码
2.1 代码方式
@Bean public Decoder decoder(){ return new CustomDecoder(); } @Bean public Encoder encoder(){ return new CustomEncoder(); } 复制代码
2.2 属性方式
feign: client: config: #想要调用的微服务的名称 msb-user: encoder: com.xxx.CustomDecoder decoder: com.xxx..CustomEncoder 复制代码
3、拦截器
通常我们调用的接口都是有权限控制的,很多时候可能认证的值是通过参数去传递的,还有就是通过请求头 去传递认证信息,比如 Basic 认证方式。
3.1 扩展点:
package feign; public interface RequestInterceptor { void apply(RequestTemplate template); } 复制代码
3.2 使用场景
- 统一添加 header 信息;
- 对 body 中的信息做修改或替换;
3.3 自定义逻辑
package com.msb.order.interceptor; import feign.RequestInterceptor; import feign.RequestTemplate; public class FeignAuthRequestInterceptor implements RequestInterceptor { private String tokenId; public FeignAuthRequestInterceptor(String tokenId) { this.tokenId = tokenId; } @Override public void apply(RequestTemplate template) { template.header("Authorization",tokenId); } } 复制代码
package com.msb.order.configuration; import com.msb.order.interceptor.FeignAuthRequestInterceptor; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class FeignConfig { @Value("${feign.tokenId}") private String tokenId; /** * 自定义拦截器 * @return */ @Bean public FeignAuthRequestInterceptor feignAuthRequestInterceptor(){ return new FeignAuthRequestInterceptor(tokenId); } } 复制代码
feign: tokenId: d874528b-a9d9-46df-ad90-b92f87ccc557 复制代码
在msb-stock项目中增加springmvc中的拦截器
拦截器代码:
package com.msb.stock.interceptor; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @Slf4j public class AuthInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { boolean flag = true; // 逻辑认证 String authorization = request.getHeader("Authorization"); log.info("获取的认证信息 Authorization:{}",authorization); if(StringUtils.hasText(authorization)){ return true; } return false; } } 复制代码
增加类配置:
package com.nx.user.interceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport; @Configuration public class WebMvcConfig extends WebMvcConfigurationSupport { @Override protected void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(new AuthInterceptor()); } 复制代码
优先级:
全局代码<全局属性<细粒度代码<细粒度属性 复制代码
4、Client 设置
Feign 中默认使用 JDK 原生的 URLConnection 发送 HTTP 请求,我们可以集成别的组件来替换掉 URLConnection,比如 Apache HttpClient,OkHttp。
4.1 扩展点
Feign发起调用真正执行逻辑:feign.Client#execute (扩展点)
public interface Client { Response execute(Request request, Options options) throws IOException; } 复制代码
4.2 配置Apache HttpClient
- 引入依赖
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-httpclient</artifactId> </dependency> 复制代码
- 修改yml配置
开启feign ,这里可以不用配置,可以参考源码分析
feign: httpclient: #使用apache httpclient做请求,而不是jdk的HttpUrlConnection enabled: true # feign最大链接数 默认200 max-connections: 200 #feign 单个路径的最大连接数 默认 50 max-connections-per-route: 50 复制代码
- 源码分析 FeignAutoConfiguration
此时默认增加一个ApacheHttpCient实现类
4.3 设置OkHttp
- 引入依赖
<dependency> <groupId>io.github.openfeign</groupId> <artifactId>feign-okhttp</artifactId> </dependency> 复制代码
- 增加配置
feign: okhttp: enabled: true #线程池可以使用httpclient的配置 httpclient: max-connections: 200 max-connections-per-route: 50 复制代码
3、源码分析 FeignAutoConfiguration
5、超时配置
通过 Options 可以配置连接超时时间和读取超时时间,Options 的第一个参数是连接的超时时间(ms), 默认值是 10s;第二个是请求处理的超时时间(ms),默认值是 60s。
Request.Options
5.1 代码配置
@Bean public Request.Options options(){ return new Request.Options(2000,50000); } 复制代码
msb-stock改造
@GetMapping("query") public User queryInfo(User user){ try { Thread.sleep(10*1000); } catch (InterruptedException e) { e.printStackTrace(); } return user; } 复制代码