ribbon的执行原理_1

调用流程

restTemplate

ResponseEntity<String> stringResponseEntity = restTemplate.postForEntity(url, map, String.class);

一直调用直到LoadBalancerInterceptor.intercept(final HttpRequest request, final byte[] body,final ClientHttpRequestExecution execution)

public ClientHttpResponse intercept(final HttpRequest request, final byte[] body,
        final ClientHttpRequestExecution execution) throws IOException {
    final URI originalUri = request.getURI();
    String serviceName = originalUri.getHost();
    Assert.state(serviceName != null,
            "Request URI does not contain a valid hostname: " + originalUri);
    //这里的loadBalancer为RibbonLoadBalancerClient
    return this.loadBalancer.execute(serviceName,
            this.requestFactory.createRequest(request, body, execution));
}

this.requestFactory.createRequest(request, body, execution)

public LoadBalancerRequest<ClientHttpResponse> createRequest(
    final HttpRequest request, final byte[] body,
    final ClientHttpRequestExecution execution) {
  return instance -> {
    HttpRequest serviceRequest = new ServiceRequestWrapper(request, instance,
        this.loadBalancer);
    if (this.transformers != null) {
      for (LoadBalancerRequestTransformer transformer : this.transformers) {
        serviceRequest = transformer.transformRequest(serviceRequest,
            instance);
      }
    }
    return execution.execute(serviceRequest, body);
  };
}

用lambda构建了并返回了LoadBalancerRequest,最终肯定还是会调用到lambda中的execution.execute(serviceRequest, body)

this.loadBalancer.execute

回到this.loadBalancer.execute

RibbonLoadBalancerClient.execute(String serviceId, LoadBalancerRequest request)

public <T> T execute(String serviceId, LoadBalancerRequest<T> request)
    throws IOException {
  return execute(serviceId, request, null);
}
public <T> T execute(String serviceId, LoadBalancerRequest<T> request, Object hint)
    throws IOException {
  //根据服务名获取ILoadBalancer类型的负载均衡器
  ILoadBalancer loadBalancer = getLoadBalancer(serviceId);
  Server server = getServer(loadBalancer, hint);
  if (server == null) {
    throw new IllegalStateException("No instances available for " + serviceId);
  }
  RibbonServer ribbonServer = new RibbonServer(serviceId, server,
      isSecure(server, serviceId),
      serverIntrospector(serviceId).getMetadata(server));

  return execute(serviceId, ribbonServer, request);
}
//根据服务名获取ILoadBalancer类型的负载均衡器  
protected ILoadBalancer getLoadBalancer(String serviceId) {
  //这里的clientFactory为SpringClientFactory
  return this.clientFactory.getLoadBalancer(serviceId);
}

SpringClientFactory.getLoadBalancer(String name)

public ILoadBalancer getLoadBalancer(String name) {
  return getInstance(name, ILoadBalancer.class);
}
public <C> C getInstance(String name, Class<C> type) {
  C instance = super.getInstance(name, type);
  if (instance != null) {
    return instance;
  }
  IClientConfig config = getInstance(name, IClientConfig.class);
  return instantiateWithConfig(getContext(name), type, config);
}

NamedContextFactory.getInstance(String name, Class type)

public <T> T getInstance(String name, Class<T> type) {
  AnnotationConfigApplicationContext context = getContext(name);
  try {
    return context.getBean(type);
  }
  catch (NoSuchBeanDefinitionException e) {
    // ignore
  }
  return null;
}

SpringClientFacotry.getContext(String name)

protected AnnotationConfigApplicationContext getContext(String name) {
  return super.getContext(name);
}

NamedContextFactory.getContext(String name)

protected AnnotationConfigApplicationContext getContext(String name) {
  if (!this.contexts.containsKey(name)) {
    synchronized (this.contexts) {
      if (!this.contexts.containsKey(name)) {
        this.contexts.put(name, createContext(name));
      }
    }
  }
  return this.contexts.get(name);
}

第一次执行到这里是拿不到的,会执行createContext(name)
createContext(String name)

protected AnnotationConfigApplicationContext createContext(String name) {
    AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    if (this.configurations.containsKey(name)) {
        for (Class<?> configuration : this.configurations.get(name)
                .getConfiguration()) {
            context.register(configuration);
        }
    }
    for (Map.Entry<String, C> entry : this.configurations.entrySet()) {
        if (entry.getKey().startsWith("default.")) {
            for (Class<?> configuration : entry.getValue().getConfiguration()) {
                context.register(configuration);
            }
        }
    }
    context.register(PropertyPlaceholderAutoConfiguration.class,
            this.defaultConfigType);
    context.getEnvironment().getPropertySources().addFirst(new MapPropertySource(
            this.propertySourceName,
            Collections.<String, Object>singletonMap(this.propertyName, name)));
    if (this.parent != null) {
        // Uses Environment from parent as well as beans
        context.setParent(this.parent);
        // jdk11 issue
        // https://github.com/spring-cloud/spring-cloud-netflix/issues/3101
        context.setClassLoader(this.parent.getClassLoader());
    }
    context.setDisplayName(generateDisplayName(name));
    context.refresh();
    return context;
}

到这里可以分析出以下流程:

  1. 当调用SpringClientFactory.getInstance时,会调用父类NamedContextFactory.getInstance
  2. 接着会调用getContext(String name)
  3. 如果contexts不包含服务name,name就会执行createContext(name),contexts为map,key为fegin服务名,value为每个服务自己的spring上下文。
private Map<String, AnnotationConfigApplicationContext> contexts = new ConcurrentHashMap<>();

NamedContextFactory#createContext方法中有一行

context.register(PropertyPlaceholderAutoConfiguration.class,
				this.defaultConfigType);

defaultConfigType在加载SpringClientFactory时加载父类NamedContextFactory进行赋值

public SpringClientFactory() {
		super(RibbonClientConfiguration.class, NAMESPACE, "ribbon.client.name");
	}

所以defaultConfigTypeRibbonClientConfiguration加载过程在下一篇分析

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值