http调用controller方法时openfeign执行流程
作者:子瞻
http调用controller的方法时
当我们通过http调用controller的方法时,openfeign的执行流程如下图所示:
图1
首先,我们比较关心的是,我们显式声明的DemoFeignClient类会被spring容器创建代理对象
具体的创建的流程是怎样的?
图2
红色方框1标明项目启动成过程中spring容器先扫描所有的资源文件转换为对目标类进行描述RootBeandefinition,然后@SpringBootApplication注解将声明的类加载到DefaultListableBeanFacrory中,此时spring框架执行org.springframework.beans.factory.support.AbstractBeanFactory.getBean(),最终通过org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean()里面的
//执行bean创建的核心逻辑 instanceWrapper = createBeanInstance(beanName, mbd, args);
完成bean创建工作。然后通过org.springframework.context.annotation.CommonAnnotationBeanPostProcessor.postProcessProperties()注入属性。
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { //获取属性信息 InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs); try { //执行属性注入逻辑 metadata.inject(bean, beanName, pvs); } catch (Throwable ex) { throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex); } return pvs; }
在执行contoller类的属性注入过程中,发现DemoFeignClient这个bean还没有被创建,因此需要递归创建emoFeignClient实例,我们推测一下肯定是要再执行一次创建bean的逻辑,流程不再赘述!
图3
由上图可以发现,spring框架创建DemoFeignClient实例是,通过描述它的RootBeanDefinition类中获取instanceSupplier,这里的值是FeignClientsRegistrar实例
FeignClientsRegistrar实例有FeignClientFacoryBean实例,然后通过FeignClientFacoryBean.getObject()方法进行真正的Feign实例。
ReflectiveFeign.newInstance()创建代理类
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); //创建DemoClient代理类 T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(), new Class<?>[] {target.type()}, handler); for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) { defaultMethodHandler.bindTo(proxy); } return proxy; }
至此,DemoFeignClient实例创建完成。接着我们定义的Controller就可以完成demoFeignClient 属性注入工作了。项目启动完成之后,当有http请求的时候,loadbalancer就通过负载均衡算法获取服务实例,通过openfeign进行远程调用获取我们想要的数据了。
以上就是http调用controller方法时openfeign执行流程的详细内容,更多关于openfeign执行流程的资料请关注脚本之家其它相关文章!