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)文章
淺談springboot中tk.mapper代碼生成器的用法說明
這篇文章主要介紹了淺談springboot中tk.mapper代碼生成器的用法說明,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-09-09解決SpringBoot的@DeleteMapping注解的方法不被調(diào)用問題
這篇文章主要介紹了解決SpringBoot的@DeleteMapping注解的方法不被調(diào)用問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-01-01java設(shè)計(jì)模式之實(shí)現(xiàn)對象池模式示例分享
對象池模式經(jīng)常用在頻繁創(chuàng)建、銷毀對象(并且對象創(chuàng)建、銷毀開銷很大)的場景,比如數(shù)據(jù)庫連接池、線程池、任務(wù)隊(duì)列池等。本代碼簡單,沒有限制對象池大小2014-02-02SpringBoot Java后端實(shí)現(xiàn)okhttp3超時設(shè)置的方法實(shí)例
Okhttp的使用沒有httpClient廣泛,網(wǎng)上關(guān)于Okhttp設(shè)置代理的方法很少,下面這篇文章主要給大家介紹了關(guān)于SpringBoot Java后端實(shí)現(xiàn)okhttp3超時設(shè)置的相關(guān)資料,需要的朋友可以參考下2021-10-10Java?web開發(fā)環(huán)境的搭建超完整步驟
這篇文章主要介紹了如何安裝和配置IDEA?2020.1.1?X64版本軟件,包括創(chuàng)建Java?Web項(xiàng)目、配置Tomcat、部署Tomcat?API以及創(chuàng)建和配置Servlet,通過這些步驟,新手可以快速搭建起Javaweb開發(fā)環(huán)境,需要的朋友可以參考下2024-11-11Java操作透明圖片并保持背景透明的實(shí)現(xiàn)
這篇文章主要介紹了Java操作透明圖片并保持背景透明的實(shí)現(xiàn),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-11-11