「这是我参与2022首次更文挑战的第8天,活动详情查看:2022首次更文挑战」。
RequestInterceptor
请求拦截器,在请求发送之前,对RequestTemplate 做出修改, 例如: 修改请求头, 请求参数等
void apply(RequestTemplate template);
参数RequestTemplate:请求HTTP目标的构建器。这个类是UriTemplate的一个变体,其中,除了uri, header和Query信息也支持模板表达式。
Logger
用于调试消息的简单日志抽象, 适配器模式,Slf4jLogger是个适配器角色, Logger(slf4j)是待适配的接口, Logger(Feign)是目标接口
Contract
定义哪些注释和值在接口上是有效的。
List<MethodMetadata> parseAndValidateMetadata(Class<?> targetType); 调用来解析链接到HTTP请求的类中的方法。
MethodMetadata 方法的元数据对象 ,包含`RequestTemplate
Options
参数Options,配置信息封装,包含:connectTimeout,connectTimeoutUnit,readTimeout,readTimeoutUnit,followRedirects(是否重定向)
Encoder
对HTTP请求体 进行编码,序列化方式的抽象
void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException;
将object 转换到 template.body中 Request.Body 包含字节数组和编码方式
Decoder
将HTTP响应解码为给定的单个对象(反序列化)
Object decode(Response response, Type type) throws IOException, DecodeException, FeignException; 将response中的内容解析, 返回值 为 Type类型的类对象, Type就是 定义的 FeignClient接口中的 方法的返回值类型描述
QueryMapEncoder
QueryMapEncoder将对象编码为查询参数名称到值的映射。 即 拼接到 Url后
Map<String, Object> encode(Object object); 将对象转换为map
ErrorDecoder
当响应结果不是2XX,404的时候, 会执行ErrorDecoder,如果需要重试,则返回RetryableException
Exception decode(String methodKey, Response response)
实现此方法,以便解码HTTP {@link Response}时
{@link Response#status()}不在2xx范围内。请引发特定于应用程序的异常
在可能的情况下。如果你的异常是可重试的,wrap或子类{@link RetryableException}
Target
类似于 javax.ws.rs.client.WebTarget
为 FeignClient的接口
Class<T> type(); 此目标所应用的接口类型
String name(); 与此目标关联的配置键。
String url();目标器的base HTTP URL。
Request apply(RequestTemplate input) 将模版转换为Request
EmptyTarget: 空实现
HardCodedTarget:硬编码
MockTarget: mock实现
LoadBalancingTarget: 负载均衡Target,对url进行动态替换
MethodHandler
方法执行器, 类似于: InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])
Object invoke(Object[] argv) throws Throwable;
DefaultMethodHandler : 适配了JDK中的MethodHandle, 使用MethodHandle进行方法的调用和绑定
SynchronousMethodHandler:同步方法调用,具备自己的内部工厂SynchronousMethodHandler.Factory,用于方便创建。 核心代码如下:
@Override
public Object invoke(Object[] argv) throws Throwable {
// 创建请求模版
RequestTemplate template = buildTemplateFromArgs.create(argv);
// 查找配置
Options options = findOptions(argv);
// 重试策略克隆
Retryer retryer = this.retryer.clone();
while (true) {
try {
// 执行调用并解码
return executeAndDecode(template, options);
} catch (RetryableException e) {
try {
// 出现重试异常进行重试
retryer.continueOrPropagate(e);
} catch (RetryableException th) {
Throwable cause = th.getCause();
if (propagationPolicy == UNWRAP && cause != null) {
throw cause;
} else {
throw th;
}
}
if (logLevel != Logger.Level.NONE) {
// 日志级别不为none , 打印重试日志
logger.logRetry(metadata.configKey(), logLevel);
}
continue;
}
}
}