













请关注微信公众号:阿呆-bot
Feign 是抽象工厂类,ReflectiveFeign 是其基于反射的实现,负责创建 HTTP API 代理实例。
public abstract class Feign {
public static Builder builder() {
return new Builder();
}
public abstract <T> T newInstance(Target<T> target);
}
public class ReflectiveFeign<C> extends Feign {
public <T> T newInstance(Target<T> target) {
Map<Method, MethodHandler> methodToHandler =
targetToHandlersByName.apply(target, requestContext);
InvocationHandler handler = factory.create(target, methodToHandler);
return (T) Proxy.newProxyInstance(
target.type().getClassLoader(), new Class<?>[] {target.type()}, handler);
}
}
Core 模块可以划分为以下业务域:
职责: 解析接口方法上的注解,生成方法元数据。
核心类:
Contract: 契约接口BaseContract: 基础契约实现DeclarativeContract: 声明式契约基类Contract.Default: 默认契约实现MethodMetadata: 方法元数据领域边界: 负责将 Java 接口方法转换为 HTTP 请求元数据,不涉及实际的 HTTP 请求执行。

职责: 处理接口方法的调用,执行 HTTP 请求并解码响应。
核心类:
MethodHandler: 方法处理器接口SynchronousMethodHandler: 同步方法处理器AsynchronousMethodHandler: 异步方法处理器DefaultMethodHandler: 默认方法处理器(处理接口默认方法)MethodHandlerConfiguration: 方法处理器配置领域边界: 负责方法调用的执行流程,包括请求构建、HTTP 执行、响应处理,但不涉及注解解析。

职责: 执行实际的 HTTP 请求,是 Feign 与底层 HTTP 库的抽象。
核心类:
Client: HTTP 客户端接口Client.Default: 默认实现(基于 HttpURLConnection)AsyncClient: 异步客户端接口领域边界: 负责 HTTP 请求的执行,不涉及请求构建和响应解码。

职责: 将 Java 对象编码为 HTTP 请求体,将 HTTP 响应体解码为 Java 对象。
核心类:
Encoder: 编码器接口Encoder.Default: 默认编码器Decoder: 解码器接口Decoder.Default: 默认解码器ErrorDecoder: 错误解码器接口领域边界: 负责对象序列化和反序列化,不涉及 HTTP 传输。

职责: 表示要调用的远程 HTTP 服务,包含服务类型、名称和基础 URL。
核心类:
Target: 目标接口Target.HardCodedTarget: 硬编码目标实现Target.EmptyTarget: 空目标实现领域边界: 负责目标服务的表示和请求模板的应用,不涉及具体的 HTTP 请求执行。

职责: 构建 HTTP 请求模板,支持 URI 模板表达式和参数替换。
核心类:
RequestTemplate: 请求模板类RequestTemplate.Factory: 请求模板工厂接口(内部接口)RequestTemplateFactoryResolver: 请求模板工厂解析器template.UriTemplate: URI 模板template.BodyTemplate: 请求体模板template.HeaderTemplate: 请求头模板template.QueryTemplate: 查询参数模板领域边界: 负责请求模板的构建和参数替换,不涉及实际的 HTTP 请求发送。

各业务域通过以下方式协作:

protected MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
final MethodMetadata data = new MethodMetadata();
data.targetType(targetType);
data.method(method);
data.returnType(Types.resolve(targetType, targetType, method.getGenericReturnType()));
data.configKey(Feign.configKey(targetType, method));
processAnnotationOnClass(data, targetType);
for (final Annotation methodAnnotation : method.getAnnotations()) {
processAnnotationOnMethod(data, methodAnnotation, method);
}
// 处理参数注解
for (int i = 0; i < parameterAnnotations.length; i++) {
processAnnotationsOnParameter(data, parameterAnnotations[i], i);
}
return data;
}
public Object invoke(Object[] argv) throws Throwable {
RequestTemplate template = methodHandlerConfiguration
.getBuildTemplateFromArgs().create(argv);
Options options = findOptions(argv);
Retryer retryer = this.methodHandlerConfiguration.getRetryer().clone();
while (true) {
try {
return executeAndDecode(template, options);
} catch (RetryableException e) {
retryer.continueOrPropagate(e);
continue;
}
}
}
Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
Request request = targetRequest(template);
Response response = client.execute(request, options);
return responseHandler.handleResponse(
methodHandlerConfiguration.getMetadata().configKey(),
response,
methodHandlerConfiguration.getMetadata().returnType(),
elapsedTime);
}
public RequestTemplate resolve(Map<String, Object> variables) {
if (variables == null || variables.isEmpty()) {
return this;
}
RequestTemplate resolved = new RequestTemplate(this);
if (uriTemplate != null) {
resolved.uriTemplate = uriTemplate.expand(variables);
}
// 解析查询参数
for (Map.Entry<String, QueryTemplate> entry : queries.entrySet()) {
resolved.queries.put(entry.getKey(), entry.getValue().expand(variables));
}
// 解析请求头
for (Map.Entry<String, HeaderTemplate> entry : headers.entrySet()) {
resolved.headers.put(entry.getKey(), entry.getValue().expand(variables));
}
return resolved;
}
Core 模块通过以下方式体现 DDD 原则:
各领域通过接口交互,实现依赖倒置:
各领域大量使用策略模式:
RequestTemplate 使用模板方法模式:
多处使用工厂模式:
Feign.builder(): 创建 Builder 工厂MethodHandler.Factory: 创建 MethodHandlerRequestTemplateFactory: 创建 RequestTemplate(RequestTemplate.Factory 的内部接口)Core 模块通过 DDD 领域划分,实现了清晰的职责分离:
各领域通过清晰的接口协作,实现了高内聚、低耦合的架构设计。这种设计使得 Feign 既灵活又可扩展,支持多种集成场景。
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。