「这是我参与2022首次更文挑战的第9天,活动详情查看:2022首次更文挑战」。
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;
}
}
}
InvocationHandlerFactory
用于创建JDK中InvocationHandler的工厂接口。
InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch);` 根据target,和方法路由, 创建出`InvocationHandler
具体创建的产品InvocationHandler查看下图:
其中设计到的设计模式有: 工厂方法, 模版方法, 装饰器
工厂方法
- 抽象工厂角色 InvocationHandlerFactory
- 抽象产品角色InvocationHandler
- 具体工厂MeteredInvocationHandleFactory,Default,ReactorFeign.ReactorInvocationHandlerFactory,RxJavaFeign.ReactorInvocationHandlerFactory
- 具体产品: 匿名lambda,ReflectiveFeign.FeignInvocationHandler,ReactorInvocationHandler,RxJavaInvocationHandler
- 用户只需要知道具体工厂的名称就可得到所要的产品,无须知道产品的具体创建过程。
- 灵活性增强,对于新产品的创建,只需多写一个相应的工厂类。
- 典型的解耦框架。高层模块只需要知道产品的抽象类,无须关心其他实现类,满足开闭原则、迪米特法则、依赖倒置原则和里氏替换原则。
模版方法
- 抽象类: ReactiveInvocationHandler
- 具体实现子类: ReactorInvocationHandler,RxJavaInvocationHandler
- 模版方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {....} - 抽象方法:
protected abstract Publisher invoke(Method method, MethodHandler methodHandler,Object[] arguments); - 在父类中提取了公共的部分代码,便于代码复用。
装饰器
- 抽象构件: InvocationHandlerFactory
- 具体构件: Default, ReactorFeign.ReactorInvocationHandlerFactory,RxJavaFeign.ReactorInvocationHandlerFactory
- 具体装饰: MeteredInvocationHandleFactory 在原有的factory生产的产品上 增加了监控功能
Feign
Feign的目的是简化对假装休息的http api的开发, 在实现中,Feign是一个{@link Feign#newInstance工厂}用于生成{@link Target targeted} HTTP api。
程序入口
Feign.builder().build().target(Target target);
同步实现: ReflectiveFeign
异步实现: AsyncFeign 还不完善
Feign.Builder主要是生产 ReflectiveFeign,核心代码:
public <T> T target(Target<T> target) {
return build().newInstance(target);
}
public Feign build() {
Client client = Capability.enrich(this.client, capabilities);
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);
Contract contract = Capability.enrich(this.contract, capabilities);
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);
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);
}
}
ReflectiveFeign, 核心代码:
// 创建target泛型中的对象
@Override
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);
// 生成代理对象, 绑定handler
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),
new Class<?>[] {target.type()}, handler);
// 代理对象上绑定默认的 方法处理
for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
defaultMethodHandler.bindTo(proxy);
}
return proxy;
}
ParseHandlersByName**
根据名称解析handler
核心代码
public Map<String, MethodHandler> apply(Target target) {
// 约束解析出方法的元数据
List<MethodMetadata> metadata = contract.parseAndValidateMetadata(target.type());
Map<String, MethodHandler> result = new LinkedHashMap<String, MethodHandler>();
for (MethodMetadata md : metadata) {
BuildTemplateByResolvingArgs buildTemplate;
if (!md.formParams().isEmpty() && md.template().bodyTemplate() == null) {
// BuildFormEncodedTemplateFromArgs 是RequestTemplate.Factory的实现类
buildTemplate =
new BuildFormEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
} else if (md.bodyIndex() != null || md.alwaysEncodeBody()) {
// BuildEncodedTemplateFromArgs 是RequestTemplate.Factory的实现类
buildTemplate = new BuildEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
} else {
// BuildTemplateByResolvingArgs 是RequestTemplate.Factory的实现类
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 {
// factory 为SynchronousMethodHandler.Factory 来创建对应的 SynchronousMethodHandler
result.put(md.configKey(),
factory.create(target, md, buildTemplate, options, decoder, errorDecoder));
}
}
return result;
}
}