OpenFeign 組件的前身是 Netflix Feign 項(xiàng)目。后來 Feign 項(xiàng)目被貢獻(xiàn)給了開源組織,才有了今天使用的 Spring Cloud OpenFeign 組件。
OpenFeign 提供了一種聲明式的遠(yuǎn)程調(diào)用接口,它可以大幅簡化遠(yuǎn)程調(diào)用的編程體驗(yàn)。用一個代碼片段看一下,由 OpenFeign 發(fā)起的遠(yuǎn)程服務(wù)調(diào)用的代碼風(fēng)格是什么樣的。
String response = helloWorldService.hello("Spring Cloud");
可以發(fā)現(xiàn),使用 OpenFeign 組件來實(shí)現(xiàn)遠(yuǎn)程調(diào)用非常簡單,就像使用本地方法一樣,只要一行代碼就能實(shí)現(xiàn) WebClient 組件好幾行代碼干的事情。而且這段代碼不包含任何業(yè)務(wù)無關(guān)的信息,完美實(shí)現(xiàn)了調(diào)用邏輯和業(yè)務(wù)邏輯之間的職責(zé)分離。
OpenFeign 組件背后的工作流程OpenFeign 使用了一種動態(tài)代理技術(shù)來封裝遠(yuǎn)程服務(wù)調(diào)用的過程,在上面的例子中看到的 helloWorldService 其實(shí)是一個特殊的接口,它是由 OpenFeign 組件中的 FeignClient 注解所聲明的接口。
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.*;
@FeignClient(value = "hello-world-service")
public interface HelloWorldService { @PostMapping("/sayHello")
String hello(String guestName);
}
遠(yuǎn)程服務(wù)調(diào)用的信息被寫在了 FeignClient 接口中。在上面的代碼里,可以看到,服務(wù)的名稱、接口類型、訪問路徑已經(jīng)通過注解做了聲明。OpenFeign 通過解析這些注解標(biāo)簽生成一個動態(tài)代理類,這個代理類會將接口調(diào)用轉(zhuǎn)化為一個遠(yuǎn)程服務(wù)調(diào)用的 Request,并發(fā)送給目標(biāo)服務(wù)。
OpenFeign 的動態(tài)代理在項(xiàng)目初始化階段,OpenFeign 會生成一個代理類,對所有通過FeignClient 接口發(fā)起的遠(yuǎn)程調(diào)用進(jìn)行動態(tài)代理。如圖:
上圖中的步驟中,在項(xiàng)目啟動階段加載完成的是 1 ~ 3步 ,只有第 4 步(調(diào)用遠(yuǎn)程服務(wù))是發(fā)生在項(xiàng)目的運(yùn)行階段。
關(guān)鍵步驟描述:
OpenFeign 組件加載過程的重要階段,如圖:
OpenFeign 動態(tài)代理類的創(chuàng)建過程:
@SpringBootApplication
@EnableFeignClients
public class HelloWorldApplication {public static void main(String[] args) {SpringApplication.run(HelloWorldApplication .class, args);
}
}
// 解析FeignClient接口方法級別上的RequestMapping注解
protected void processAnnotationOnMethod(MethodMetadata data, Annotation methodAnnotation, Method method) { // 如果方法上沒有使用RequestMapping注解,則不進(jìn)行解析
// 其實(shí)GetMapping、PostMapping等注解都屬于RequestMapping注解
if (!RequestMapping.class.isInstance(methodAnnotation)
&& !methodAnnotation.annotationType().isAnnotationPresent(RequestMapping.class)) { return;
}
// 獲取RequestMapping注解實(shí)例
RequestMapping methodMapping = findMergedAnnotation(method, RequestMapping.class);
// 解析Http Method定義,即注解中的GET、POST、PUT、DELETE方法類型
RequestMethod[] methods = methodMapping.method();
// 如果沒有定義methods屬性則默認(rèn)當(dāng)前方法是個GET方法
if (methods.length == 0) { methods = new RequestMethod[] {RequestMethod.GET };
}
checkOne(method, methods, "method");
data.template().method(Request.HttpMethod.valueOf(methods[0].name()));
// 解析Path屬性,即方法上寫明的請求路徑
checkAtMostOne(method, methodMapping.value(), "value");
if (methodMapping.value().length >0) { String pathValue = emptyToNull(methodMapping.value()[0]);
if (pathValue != null) { pathValue = resolve(pathValue);
// 如果path沒有以斜杠開頭,則補(bǔ)上/
if (!pathValue.startsWith("/") && !data.template().path().endsWith("/")) {pathValue = "/" + pathValue;
}
data.template().uri(pathValue, true);
if (data.template().decodeSlash() != decodeSlash) {data.template().decodeSlash(decodeSlash);
}
}
}
// 解析RequestMapping中定義的produces屬性
parseProduces(data, method, methodMapping);
// 解析RequestMapping中定義的consumer屬性
parseConsumes(data, method, methodMapping);
// 解析RequestMapping中定義的headers屬性
parseHeaders(data, method, methodMapping);
data.indexToExpander(new LinkedHashMap<>());
}
通過上面的方法可以看到,OpenFeign 對 RequestMappings 注解的各個屬性都做了解析。
如果項(xiàng)目中使用的是 GetMapping、PostMapping 之類的注解,沒有使用 RequestMapping,那么 OpenFeign 也可以解析。以 GetMapping 為例,它對 RequestMapping 注解做了一層封裝。如下代碼片段,這個注解頭上也掛了一個 RequestMapping 注解。因此 OpenFeign 可以正確識別 GetMapping 并完成加載。
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@RequestMapping(method = RequestMethod.GET)
public @interface GetMapping {// ...省略部分代碼
}
OpenFeign調(diào)用過程OpenFeign 其實(shí)底層調(diào)用的是 Feign 的方法,生成了代理類,使用的是 JDK 的動態(tài)代理,然后 bean 注入。
調(diào)用過程,就是代理類作為客戶端向被調(diào)用方發(fā)送請求,接收相應(yīng)的過程。其中,feign 自行封裝了 JDK java.net 相關(guān)的網(wǎng)絡(luò)請求方法,請求過程中還有 Loadbalancer 進(jìn)行負(fù)載均衡;收到響應(yīng)后,還會對響應(yīng)類進(jìn)行解析,取出正確的響應(yīng)信息。
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機(jī)房具備T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧
本文名稱:OpenFeign基本介紹和原理了解-創(chuàng)新互聯(lián)
網(wǎng)頁URL:http://www.rwnh.cn/article40/gdpho.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站內(nèi)鏈、全網(wǎng)營銷推廣、云服務(wù)器、品牌網(wǎng)站建設(shè)、網(wǎng)站導(dǎo)航、外貿(mào)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容