作用
在build方法中我們創(chuàng)建的第二個(gè)重要組件痢艺。
觀(guān)察它的apply方法可以猜到ParseHandlersByName的作用就是我們傳入Target(封裝了我們的模擬接口累奈,要訪(fǎng)問(wèn)的域名),返回這個(gè)接口下的各個(gè)方法,對(duì)應(yīng)的執(zhí)行HTTP請(qǐng)求需要的一系列信息。
結(jié)果Map<String, MethodHandler>的key是這個(gè)接口中的方法名字骡技,MethodHandler則是包含此方法執(zhí)行需要的各種信息。
public Map<String, MethodHandler> apply(Target key)
創(chuàng)建
private final Contract contract;
private final Options options;
private final Encoder encoder;
private final Decoder decoder;
private final ErrorDecoder errorDecoder;
private final SynchronousMethodHandler.Factory factory;
ParseHandlersByName的創(chuàng)建除了我們?cè)赽uild方法里面創(chuàng)建好的SynchronousMethodHandler.Factory(http://www.reibang.com/p/b11af0b51a72)以外羞反。還有其他幾個(gè)組件:
- Contract
作用是將我們傳入的接口進(jìn)行解析驗(yàn)證布朦,看注解的使用是否符合規(guī)范,然后返回給我們接口上各種相應(yīng)的元數(shù)據(jù)昼窗。所以叫合約是趴。詳見(jiàn):http://www.reibang.com/p/6582f8319f72 - Options
封裝Request請(qǐng)求的 連接超時(shí)=默認(rèn)10s ,讀取超時(shí)=默認(rèn)60s - Encoder
怎么把我們的請(qǐng)求編碼 - Decoder
怎么把我們執(zhí)行HTTP請(qǐng)求后得到的結(jié)果解碼為我們定義的類(lèi)型 - ErrorDecoder
怎么在我們執(zhí)行HTTP請(qǐng)求后得到的錯(cuò)誤(既不是2xx的狀態(tài)碼)解碼為我們定義的類(lèi)型
所以前面五種組件的作用加起來(lái)是在干嘛呢澄惊?準(zhǔn)備一個(gè)http請(qǐng)求執(zhí)行前的各種數(shù)據(jù)唆途,定義http執(zhí)行后對(duì)于結(jié)果的各種處理邏輯。
隨意這些組件的作用是 “處理每個(gè)HTTP執(zhí)行前后的事情”
接著加上我們傳入SynchronousMethodHandler.Factory的各種組件掸驱,還記得他們的作用么:“執(zhí)行HTTP請(qǐng)求”肛搬。
所以當(dāng)ParseHandlersByName這個(gè)組件創(chuàng)建好的時(shí)候,我們就已經(jīng)準(zhǔn)備好了執(zhí)行這個(gè)HTTP請(qǐng)求所需要的一切了亭敢。
所以build方法的前2個(gè)組件包含了 “執(zhí)行HTTP請(qǐng)求”和“處理每個(gè)HTTP執(zhí)行前后的事情”的能力滚婉。最后合并到了ParseHandlersByName中。
public Feign build() {
SynchronousMethodHandler.Factory synchronousMethodHandlerFactory =
new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors, logger,
logLevel, decode404);
ParseHandlersByName handlersByName =
new ParseHandlersByName(contract, options, encoder, decoder,
errorDecoder, synchronousMethodHandlerFactory);
return new ReflectiveFeign(handlersByName, invocationHandlerFactory);
}
使用
ParseHandlersByName最后把以上的組件都封裝為了一個(gè)結(jié)果集Map<String, MethodHandler>
public Map<String, MethodHandler> apply(Target key) {
//如上文所提帅刀,contract抽取了接口上的元信息,封裝到了MethodMetadata里面远剩。
//包含我們?cè)诮涌诜椒ㄉ嫌米⒔馓砑拥囊幌盗行畔⒖勰纭T斠?jiàn):http://www.reibang.com/p/6582f8319f72
List<MethodMetadata> metadata = contract.parseAndValidatateMetadata(key.type());
//new 結(jié)果容器
Map<String, MethodHandler> result = new LinkedHashMap<String, MethodHandler>();
//遍歷抽取出的MethodMetadata。
for (MethodMetadata md : metadata) {
BuildTemplateByResolvingArgs buildTemplate;
//當(dāng)metadata里面有formParams并且bodyTemplate為空瓜晤,說(shuō)明請(qǐng)求的參數(shù)就是簡(jiǎn)單的Query參數(shù)锥余。
if (!md.formParams().isEmpty() && md.template().bodyTemplate() == null) {
buildTemplate = new BuildFormEncodedTemplateFromArgs(md, encoder);
} else if (md.bodyIndex() != null) {
buildTemplate = new BuildEncodedTemplateFromArgs(md, encoder);
} else {
buildTemplate = new BuildTemplateByResolvingArgs(md);
}
result.put(md.configKey(),
factory.create(key, md, buildTemplate, options, decoder, errorDecoder));
}
return result;
}
}