feign源码解析--fegin的执行过程

一执行逻辑

通过上篇文章分析我们知道,fegin客户端在初始化的时候,会通过jdk动态代理未为每个feignClient生成一个代理类,jdk动态代理主要是通过InvocationHandler接口的实现代理的增强.我们来看看生成代理时InvocationHandler接口的实现是如何创建的

// 通过InvocationHandlerFactory创建InvocationHandlerFactory
InvocationHandler handler = factory.create(target, methodToHandler);
    T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),
        new Class<?>[] {target.type()}, handler);

通过InvocationHandlerFactory 我们可以发现创建的是ReflectiveFeign.FeignInvocationHandler,通过ReflectiveFeign.FeignInvocationHandler来实现动态代理的底层逻辑

public interface InvocationHandlerFactory {

  InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch);

  /**
   * Like {@link InvocationHandler#invoke(Object, java.lang.reflect.Method, Object[])}, except for a
   * single method.
   */
  interface MethodHandler {

    Object invoke(Object[] argv) throws Throwable;
  }

  static final class Default implements InvocationHandlerFactory {

    @Override
    public InvocationHandler create(Target target, Map<Method, MethodHandler> dispatch) {
      return new ReflectiveFeign.FeignInvocationHandler(target, dispatch);
    }
  }
}

我们可以来看看ReflectiveFeign.FeignInvocationHandler底层是如何处理的,主要是InvocationHandler接口的invoke()的实现
我们可以看到这里主要是对equals和hashCode等的处理,最终会如何处理呢,通过断点我们发现最终会调用SynchronousMethodHandler来实现逻辑的增强处理

@Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
      if ("equals".equals(method.getName())) {
        try {
          Object otherHandler =
              args.length > 0 && args[0] != null ? Proxy.getInvocationHandler(args[0]) : null;
          return equals(otherHandler);
        } catch (IllegalArgumentException e) {
          return false;
        }
      } else if ("hashCode".equals(method.getName())) {
        return hashCode();
      } else if ("toString".equals(method.getName())) {
        return toString();
      }

      return dispatch.get(method).invoke(args);
    }

那我们看看SynchronousMethodHandler做了那些处理

@Override
  public Object invoke(Object[] argv) throws Throwable {
  	// 根据方法参数转换成一个标准的RequestTemplate 
    RequestTemplate template = buildTemplateFromArgs.create(argv);
    // 将参数转换成一个相应选项
    Options options = findOptions(argv);
    // 获得fegin的重试相关数据
    Retryer retryer = this.retryer.clone();
    while (true) {
      try {
      	// 相关增强实现
        return executeAndDecode(template, options);
      } catch (RetryableException e) {
        try {
         // 发生错误是实现增强增强
          retryer.continueOrPropagate(e);
        } catch (RetryableException th) {
          Throwable cause = th.getCause();
          if (propagationPolicy == UNWRAP && cause != null) {
            throw cause;
          } else {
            throw th;
          }
        }
        if (logLevel != Logger.Level.NONE) {
          logger.logRetry(metadata.configKey(), logLevel);
        }
        continue;
      }
    }
  }

executeAndDecode方法是如何出现处理的呢

  • fegin拦截器相关执行
  • 调用RetryableFeignBlockingLoadBalancerClient处理请求
  • 异步解析和响应解析
Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
	// 调用fegin所有的拦截器,并执行里面的相关逻辑 将template转换为feign内部的request
    Request request = targetRequest(template);

	// 打印日志
    if (logLevel != Logger.Level.NONE) {
      logger.logRequest(metadata.configKey(), logLevel, request);
    }

    Response response;
    long start = System.nanoTime();
    try {
    	// 调用RetryableFeignBlockingLoadBalancerClient进行处理
      response = client.execute(request, options);
      // ensure the request is set. TODO: remove in Feign 12
      response = response.toBuilder()
          .request(request)
          .requestTemplate(template)
          .build();
    } catch (IOException e) {
      if (logLevel != Logger.Level.NONE) {
        logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime(start));
      }
      throw errorExecuting(request, e);
    }
    // 请求处理时间
    long elapsedTime = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - start);


    if (decoder != null)
    	// 解析请求结果
      return decoder.decode(response, metadata.returnType());

	// 异步结果处理
    CompletableFuture<Object> resultFuture = new CompletableFuture<>();
    asyncResponseHandler.handleResponse(resultFuture, metadata.configKey(), response,
        metadata.returnType(),
        elapsedTime);

    try {
      if (!resultFuture.isDone())
        throw new IllegalStateException("Response handling not done");

      return resultFuture.join();
    } catch (CompletionException e) {
      Throwable cause = e.getCause();
      if (cause != null)
        throw cause;
      throw e;
    }
  }
Request targetRequest(RequestTemplate template) {
	// 遍历所有的拦截器,执行拦截中响应的业务逻辑
    for (RequestInterceptor interceptor : requestInterceptors) {
      interceptor.apply(template);
    }
    return target.apply(template);
  }

在RetryableFeignBlockingLoadBalancerClient中的excute主要做了那些处理呢

  • 更具现有的负载均衡策略,实现客户端的负载均衡
  • 通过http的相关代理实现最终的请求
@Override
	public Response execute(Request request, Request.Options options) throws IOException {
		//  获得URI 
		final URI originalUri = URI.create(request.url());
		// 获取客户端id
		String serviceId = originalUri.getHost();
		Assert.state(serviceId != null, "Request URI does not contain a valid hostname: " + originalUri);
		final LoadBalancedRetryPolicy retryPolicy = loadBalancedRetryFactory.createRetryPolicy(serviceId,
				loadBalancerClient);
		// 构建重试retryTemplate 
		RetryTemplate retryTemplate = buildRetryTemplate(serviceId, request, retryPolicy);
		return retryTemplate.execute(context -> {
			Request feignRequest = null;
			ServiceInstance retrievedServiceInstance = null;
			Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator
					.getSupportedLifecycleProcessors(
							loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class),
							RetryableRequestContext.class, ResponseData.class, ServiceInstance.class);
			String hint = getHint(serviceId);
			DefaultRequest<RetryableRequestContext> lbRequest = new DefaultRequest<>(
					new RetryableRequestContext(null, buildRequestData(request), hint));
			// On retries the policy will choose the server and set it in the context
			// and extract the server and update the request being made
			if (context instanceof LoadBalancedRetryContext) {
				LoadBalancedRetryContext lbContext = (LoadBalancedRetryContext) context;
				ServiceInstance serviceInstance = lbContext.getServiceInstance();
				if (serviceInstance == null) {
					if (LOG.isDebugEnabled()) {
						LOG.debug("Service instance retrieved from LoadBalancedRetryContext: was null. "
								+ "Reattempting service instance selection");
					}
					ServiceInstance previousServiceInstance = lbContext.getPreviousServiceInstance();
					lbRequest.getContext().setPreviousServiceInstance(previousServiceInstance);
					supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest));
					// 根据当前请求的服务id实现客户端的负载均衡
					retrievedServiceInstance = loadBalancerClient.choose(serviceId, lbRequest);
					if (LOG.isDebugEnabled()) {
						LOG.debug(String.format("Selected service instance: %s", retrievedServiceInstance));
					}
					lbContext.setServiceInstance(retrievedServiceInstance);
				}

				if (retrievedServiceInstance == null) {
					if (LOG.isWarnEnabled()) {
						LOG.warn("Service instance was not resolved, executing the original request");
					}
					org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(
							retrievedServiceInstance);
					supportedLifecycleProcessors.forEach(lifecycle -> lifecycle
							.onComplete(new CompletionContext<ResponseData, ServiceInstance, RetryableRequestContext>(
									CompletionContext.Status.DISCARD, lbRequest, lbResponse)));
					feignRequest = request;
				}
				else {
					if (LOG.isDebugEnabled()) {
						LOG.debug(String.format("Using service instance from LoadBalancedRetryContext: %s",
								retrievedServiceInstance));
					}
					String reconstructedUrl = loadBalancerClient.reconstructURI(retrievedServiceInstance, originalUri)
							.toString();
					feignRequest = buildRequest(request, reconstructedUrl);
				}
			}
			org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(
					retrievedServiceInstance);
			// 通过http的相关代理实现最终的请求
			Response response = LoadBalancerUtils.executeWithLoadBalancerLifecycleProcessing(delegate, options,
					feignRequest, lbRequest, lbResponse, supportedLifecycleProcessors,
					retrievedServiceInstance != null);
			int responseStatus = response.status();
			if (retryPolicy != null && retryPolicy.retryableStatusCode(responseStatus)) {
				if (LOG.isDebugEnabled()) {
					LOG.debug(String.format("Retrying on status code: %d", responseStatus));
				}
				response.close();
				throw new RetryableStatusCodeException(serviceId, responseStatus, response, URI.create(request.url()));
			}
			return response;
		}, new LoadBalancedRecoveryCallback<Response, Response>() {
			@Override
			protected Response createResponse(Response response, URI uri) {
				return response;
			}
		});
	}

你可能感兴趣的:(feign源码解析,java,spring,后端)