http調(diào)用controller方法時openfeign執(zhí)行流程
http調(diào)用controller的方法時
當(dāng)我們通過http調(diào)用controller的方法時,openfeign的執(zhí)行流程如下圖所示:

圖1
首先,我們比較關(guān)心的是,我們顯式聲明的DemoFeignClient類會被spring容器創(chuàng)建代理對象
具體的創(chuàng)建的流程是怎樣的?

圖2
紅色方框1標(biāo)明項(xiàng)目啟動成過程中spring容器先掃描所有的資源文件轉(zhuǎn)換為對目標(biāo)類進(jìn)行描述RootBeandefinition,然后@SpringBootApplication注解將聲明的類加載到DefaultListableBeanFacrory中,此時spring框架執(zhí)行org.springframework.beans.factory.support.AbstractBeanFactory.getBean(),最終通過org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean()里面的
//執(zhí)行bean創(chuàng)建的核心邏輯 instanceWrapper = createBeanInstance(beanName, mbd, args);
完成bean創(chuàng)建工作。然后通過org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties()注入屬性。
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//獲取屬性信息
InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
try {
//執(zhí)行屬性注入邏輯
metadata.inject(bean, beanName, pvs);
}
catch (Throwable ex) {
throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
}
return pvs;
}在執(zhí)行contoller類的屬性注入過程中,發(fā)現(xiàn)DemoFeignClient這個bean還沒有被創(chuàng)建,因此需要遞歸創(chuàng)建emoFeignClient實(shí)例,我們推測一下肯定是要再執(zhí)行一次創(chuàng)建bean的邏輯,流程不再贅述!

圖3
由上圖可以發(fā)現(xiàn),spring框架創(chuàng)建DemoFeignClient實(shí)例是,通過描述它的RootBeanDefinition類中獲取instanceSupplier,這里的值是FeignClientsRegistrar實(shí)例
FeignClientsRegistrar實(shí)例有FeignClientFacoryBean實(shí)例,然后通過FeignClientFacoryBean.getObject()方法進(jìn)行真正的Feign實(shí)例。
ReflectiveFeign.newInstance()創(chuàng)建代理類
public <T> T newInstance(Target<T> target) {
//DemoFeignClient 的方法信息 key 方法名稱 value method信息
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);
//創(chuàng)建DemoClient代理類
T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),
new Class<?>[] {target.type()}, handler);
for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
defaultMethodHandler.bindTo(proxy);
}
return proxy;
}至此,DemoFeignClient實(shí)例創(chuàng)建完成。接著我們定義的Controller就可以完成demoFeignClient 屬性注入工作了。項(xiàng)目啟動完成之后,當(dāng)有http請求的時候,loadbalancer就通過負(fù)載均衡算法獲取服務(wù)實(shí)例,通過openfeign進(jìn)行遠(yuǎn)程調(diào)用獲取我們想要的數(shù)據(jù)了。
以上就是http調(diào)用controller方法時openfeign執(zhí)行流程的詳細(xì)內(nèi)容,更多關(guān)于openfeign執(zhí)行流程的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Java使用validation攔截非法提交的數(shù)據(jù)的方法實(shí)現(xiàn)
這篇文章主要介紹了Java使用validation攔截非法提交的數(shù)據(jù),包含依賴引入、實(shí)體類注解配置、控制器@Valid/@Validated使用規(guī)范,具有一定的參考價值,感興趣的可以了解一下2025-07-07
Java如何使用逆波蘭式(后綴表達(dá)式)計(jì)算表達(dá)式的值
這篇文章主要介紹了Java如何使用逆波蘭式(后綴表達(dá)式)計(jì)算表達(dá)式的值,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-06-06
spring?cloud中Feign導(dǎo)入jar失敗的問題及解決方案
這篇文章主要介紹了spring?cloud中Feign導(dǎo)入jar失敗的問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
jenkins配置詳細(xì)指南(附j(luò)dk多個版本配置)
Jenkins是一款CICD(持續(xù)集成與持續(xù)交付)工具,Jenkins可以幫你在寫完代碼后,一鍵完成開發(fā)過程中的一系列自動化部署的工作,這篇文章主要給大家介紹了關(guān)于jenkins配置的相關(guān)資料,文中還附j(luò)dk多個版本配置指南,需要的朋友可以參考下2024-02-02
Java深入學(xué)習(xí)圖形用戶界面GUI之創(chuàng)建窗體
圖形編程中,窗口是一個重要的概念,窗口其實(shí)是一個矩形框,應(yīng)用程序可以使用其從而達(dá)到輸出結(jié)果和接受用戶輸入的效果,學(xué)習(xí)了GUI就讓我們用它來創(chuàng)建一個窗體2022-05-05
Spring boot監(jiān)控Actuator-Admin實(shí)現(xiàn)過程詳解
這篇文章主要介紹了Spring boot監(jiān)控Actuator-Admin實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-09-09

