Feign的执行流程
Weather weather = Feign.builder()
.client(new Client.Default(null,null))
.decoder(new Decoder.Default())
.encoder(new Encoder.Default())
.target(Weather.class, "http://t.weather.sojson.com/api/weather/city/101030100");
从上面可以看到Feign做完build之后通过调用target()
方法直接就返回了我们想要的结果,接下来一点点探索各个方法都做了什么。
builder()
public static class Builder {
// 请求拦截器
private final List<RequestInterceptor> requestInterceptors =
new ArrayList<RequestInterceptor>();
// 日志级别
private Logger.Level logLevel = Logger.Level.NONE;
// 凭证信息
private Contract contract = new Contract.Default();
// 请求client
private Client client = new Client.Default(null, null);
// 重试器
private Retryer retryer = new Retryer.Default();
// 日志打印器
private Logger logger = new NoOpLogger();
// 编码器
private Encoder encoder = new Encoder.Default();
// 解码器
private Decoder decoder = new Decoder.Default();
// QueryMap编码器
private QueryMapEncoder queryMapEncoder = new FieldQueryMapEncoder();
// 错误解码器
private ErrorDecoder errorDecoder = new ErrorDecoder.Default();
// 请求参数(超时、连接时间等配置)
private Options options = new Options();
// 代理工厂
private InvocationHandlerFactory invocationHandlerFactory =
new InvocationHandlerFactory.Default();
// 404是否处理
private boolean decode404;
// 解码后关闭连接
private boolean closeAfterDecode = true;
private ExceptionPropagationPolicy propagationPolicy = NONE;
// 强制转换编码
private boolean forceDecoding = false;
// 增强解析器
private List<Capability> capabilities = new ArrayList<>();
}
从上文中可以看到在builder中包含了基本上feign的所有核心的内容。
target()
public <T> T target(Class<T> apiType, String url) {
// 创建硬编码Target对象
return target(new HardCodedTarget<T>(apiType, url));
}
public <T> T target(Target<T> target) {
// 构造并创建实例对象
return build().newInstance(target);
}
public interface Target<T> {
// 返回对象类型
Class<T> type();
// key名称
String name();
// 请求地址
String url();
// 构建Request
public Request apply(RequestTemplate input);
}
上文中可以看到最终创建了一个HardCodedTarget
,实现了Target
接口。接下来看下build
方法和newInstance
方法都做了什么操作。
build()
public Feign build() {
// 请求Client信息,默认HttpURLConnection
Client client = Capability.enrich(this.client, capabilities);
// 重试机制默认请求间隔100毫秒,最大重试间隔1秒,最多重试5次
Retryer retryer = Capability.enrich(this.retryer, capabilities);
// 请求拦截器
List<RequestInterceptor> requestInterceptors = this.requestInterceptors.stream()
.map(ri -> Capability.enrich(ri, capabilities))
.collect(Collectors.toList());
// 日志处理器
Logger logger = Capability.enrich(this.logger, capabilities);
// 契约信息,也就是定义了@Headers、@RequestLine、@Body、@Param等注解的处理器
Contract contract = Capability.enrich(this.contract, capabilities);
// 选项信息,配置Http请求的连接超时时间,读取超时时间
Options options = Capability.enrich(this.options, capabilities);
// 编码器
Encoder encoder = Capability.enrich(this.encoder, capabilities);
// 解码器
Decoder decoder = Capability.enrich(this.decoder, capabilities);
// 代理处理工厂
InvocationHandlerFactory invocationHandlerFactory =
Capability.enrich(this.invocationHandlerFactory, capabilities);
// 查询Encoder
QueryMapEncoder queryMapEncoder = Capability.enrich(this.queryMapEncoder, capabilities);
// 同步方法是处理器
SynchronousMethodHandler.Factory synchronousMethodHandlerFactory =
new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors, logger,
logLevel, decode404, closeAfterDecode, propagationPolicy, forceDecoding);
// 根据名称转换
ParseHandlersByName handlersByName =
new ParseHandlersByName(contract, options, encoder, decoder, queryMapEncoder,
errorDecoder, synchronousMethodHandlerFactory);
return new ReflectiveFeign(handlersByName, invocationHandlerFactory, queryMapEncoder);
}
build后,从Capability中再次解析,构建了代理处理工厂和同步处理器。最后创建了一个ReflectiveFeign
实例对象。创建实例的时候传入了handlersByName
,invocationHandlerFactory
,queryMapEncoder
三个参数。
ReflectiveFeign的newInstance方法
public <T> T newInstance(Target<T> target) {
// 构建方法名和处理器的关系
Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);
Map<Method, MethodHandler> methodToHandler = new LinkedHashMap<Method, MethodHandler>();
List<DefaultMethodHandler> defaultMethodHandlers = new LinkedList<DefaultMethodHandler>();
// 获取方法循环
for (Method method : target.type().getMethods()) {
if (method.getDeclaringClass() == Object.class) {
continue;
} else if (Util.isDefault(method)) {
DefaultMethodHandler handler = new DefaultMethodHandler(method);
defaultMethodHandlers.add(handler);
methodToHandler.put(method, handler);
} else {
// 方法处理器
methodToHandler.put(method, nameToHandler.get(Feign.configKey(target.type(), method)));
}
}
// 创建代理处理器
InvocationHandler handler = factory.create(target, methodToHandler);
// 创建代理实例对象
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),
new Class<?>[] {target.type()}, handler);
// 循环绑定默认方法
for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
defaultMethodHandler.bindTo(proxy);
}
return proxy;
}
接下来看下Map<String, MethodHandler> nameToHandler = targetToHandlersByName.apply(target);
处理器的获取方案是如何获取的。然后在看下工厂处理方法。
targetToHandlersByName.apply
public Map<String, MethodHandler> apply(Target target) {
// 转换并且验证生成当前target的metadata
List<MethodMetadata> metadata = contract.parseAndValidateMetadata(target.type());
Map<String, MethodHandler> result = new LinkedHashMap<String, MethodHandler>();
// 循环metadata
for (MethodMetadata md : metadata) {
BuildTemplateByResolvingArgs buildTemplate;
if (!md.formParams().isEmpty() && md.template().bodyTemplate() == null) {
// 构建模板信息
buildTemplate =
new BuildFormEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
} else if (md.bodyIndex() != null) {
// 构建模板信息
buildTemplate = new BuildEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
} else {
// 构建模板信息
buildTemplate = new BuildTemplateByResolvingArgs(md, queryMapEncoder, target);
}
if (md.isIgnored()) {
result.put(md.configKey(), args -> {
throw new IllegalStateException(md.configKey() + " is not a method handled by feign");
});
} else {
result.put(md.configKey(),
// 创建代理信息
factory.create(target, md, buildTemplate, options, decoder, errorDecoder));
}
}
return result;
}
public MethodHandler create(Target<?> target,
MethodMetadata md,
RequestTemplate.Factory buildTemplateFromArgs,
Options options,
Decoder decoder,
ErrorDecoder errorDecoder) {
return new SynchronousMethodHandler(target, client, retryer, requestInterceptors, logger,
logLevel, md, buildTemplateFromArgs, options, decoder,
errorDecoder, decode404, closeAfterDecode, propagationPolicy, forceDecoding);
}
最终可以看到创建了key和SynchronousMethodHandler的实例关系的map进行返回。
factory.create
// 创建代理处理器
InvocationHandler handler = factory.create(target, methodToHandler);
// 创建代理实例对象
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),
new Class<?>[] {target.type()}, handler);
// 默认动态代理处理工程
static final class Default implements InvocationHandlerFactory {
@Override
public InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch) {
// 反射处理代理处理器
return new ReflectiveFeign.FeignInvocationHandler(target, dispatch);
}
}