Feign目标方法代理流程

发布时间:2024年01月22日

总体而言Feign调用目标方法之前被jdk动态代理区分为两种形式:负载均衡方式以及域名直接调用方式。

public class FeignClientFactoryBean{
	
	public <T> T getTarget() {
		//通过父容器创建子容器工厂类FeignContext
		FeignContext context = applicationContext.getBean(FeignContext.class);
		// 通过子容器 FeignContext 为每个Feign客户端创建 Feign.Builder
		Feign.Builder builder = feign(context);
		//如果FeignClient注解存在URL配置则直接调用,否则通过ribbon负载均衡
		if (!StringUtils.hasText(this.url)) {
			...
			HardCodedTarget target = new HardCodedTarget<>(this.type, this.name, this.url);
			// 通常选择负载均衡方式
			return (T) loadBalance(builder, context, target);
		}
		...
        String url = this.url + cleanPath();
        // LazyTracingFeignClient
		Client client = getOptional(context, Client.class);
		if (client != null) {
			if (client instanceof FeignBlockingLoadBalancerClient) {
				client = ((FeignBlockingLoadBalancerClient) client).getDelegate();
			}
			if (client instanceof RetryableFeignBlockingLoadBalancerClient) {
				client = ...
			}
			builder.client(client);
		}
		applyBuildCustomizers(context, builder);
        Targeter targeter = get(context, Targeter.class);
		HardCodedTarget target = new HardCodedTarget<>(this.type, this.name, this.url);
		return (T) targeter.target(this, builder, context,target);//域名调用方式
	}
}

?HardCodedTarget中其中type是指Feign客户端接口类型。注意区别于Targeter。


1.负载均衡之TraceFeignBlockingLoadBalancerClient

该方式适用于服务治理过程中,代理的原因是为了真正调用目标方法之前完成服务端负载均衡策略。

public class FeignClientFactoryBean implements FactoryBean<Object>, InitializingBean {
		protected <T> T loadBalance(Feign.Builder builder, FeignContext context, HardCodedTarget<T> target) {
				Client client = getOptional(context, Client.class);
                //TraceFeignBlockingLoadBalancerClient || LoadBalancerFeignClient,区别于域名调用方式client之LazyTracingFeignClient
				if (client != null) {
					builder.client(client);
					applyBuildCustomizers(context, builder);//扩展点
					Targeter targeter = get(context, Targeter.class);//从子容器获取 FeignCircuitBreakerTargeter
					return targeter.target(this, builder, context, target);
				}
		}
}

1.1.FeignCircuitBreakerTargeter

class FeignCircuitBreakerTargeter implements Targeter {
	
	public <T> T target(FeignClientFactoryBean factory, Feign.Builder feign,FeignContext context,Target.HardCodedTarget<T> target) {
		// 如果没有显式设置 HystrixFeign 的开关,默认Builder 为 抽象类Feign内部静态类
		if (!(feign instanceof feign.hystrix.HystrixFeign.Builder)) {
			return feign.target(target);// 忽略Feign降级功能
		}
		FeignCircuitBreaker.Builder builder = (FeignCircuitBreaker.Builder) feign;
		String name = StringUtils.isEmpty(factory.getContextId()) ? factory.getName(): factory.getContextId();
		Class<?> fallback = factory.getFallback();
		if (fallback != void.class) {// 优先通过Fallback实现Feign降级功能
			return targetWithFallback(name, context, target, builder, fallback);
		}
		Class<?> fallbackFactory = factory.getFallbackFactory();
		if (fallbackFactory != void.class) {// 其次通过FallbackFactory实现Feign降级功能
			return targetWithFallbackFactory(name, context, target, builder,fallbackFactory);
		}
		return feign.target(target);// 忽略Feign降级功能
	}


	private <T> T targetWithFallbackFactory(String feignClientName, FeignContext context,Target.HardCodedTarget<T> target,
														FeignCircuitBreaker.Builder builder, Class<?> fallbackFactoryClass) {
		// 服务熔断或者降级工厂类
		FallbackFactory<? extends T> fallbackFactory = (FallbackFactory<? extends T>) getFromContext("fallbackFactory",
				feignClientName, context, fallbackFactoryClass, FallbackFactory.class);
		return builder(feignClientName, builder).target(target, fallbackFactory);
	}

	private FeignCircuitBreaker.Builder builder(String feignClientName, FeignCircuitBreaker.Builder builder) {
		// 初始化 Feign.Builder 相关的一些参数
		return builder.circuitBreakerFactory(circuitBreakerFactory)
			.feignClientName(feignClientName)
			//feign.circuitbreaker.group.enabled配置
			.circuitBreakerGroupEnabled(circuitBreakerGroupEnabled)
			.circuitBreakerNameResolver(circuitBreakerNameResolver);
	}
}
public final class FeignCircuitBreaker {

	public static Builder builder() {
		return new Builder();
	}

	public static final class Builder extends Feign.Builder {

		private CircuitBreakerFactory circuitBreakerFactory;

		private String feignClientName;

		private boolean circuitBreakerGroupEnabled;

		...

		public <T> T target(Target<T> target, FallbackFactory<? extends T> fallbackFactory) {
            // 利用ReflectiveFeign完成当前Feign客户端的jdk动态代理
			return build(fallbackFactory).newInstance(target);
		}

		public Feign build(final FallbackFactory<?> nullableFallbackFactory) {
			// 初始化抽象类 Feign.Builder 相关的一些参数
			super.invocationHandlerFactory((target, dispatch) -> new FeignCircuitBreakerInvocationHandler(
					circuitBreakerFactory, feignClientName, target, dispatch, nullableFallbackFactory,
					circuitBreakerGroupEnabled, circuitBreakerNameResolver));
			//初始化抽象类 Feign.Builder父类BaseBuilder 相关的一些参数
            return super.build();
		}

	}

}

?FeignCircuitBreakerInvocationHandler是JDK动态代理中设置处理器InvocationHandler。

public abstract class Feign {
	
	public static class Builder extends BaseBuilder<Builder> {

		public Feign build() {
		      super.enrich();
		      SynchronousMethodHandler.Factory synchronousMethodHandlerFactory =
			          new SynchronousMethodHandler.Factory(client, retryer, requestInterceptors,
			              responseInterceptor, logger, logLevel, dismiss404, closeAfterDecode,
			              propagationPolicy, forceDecoding);
		      ParseHandlersByName handlersByName =
			          new ParseHandlersByName(contract, options, encoder, decoder, queryMapEncoder,
			              errorDecoder, synchronousMethodHandlerFactory);
			  // invocationHandlerFactory抽象类 Feign.Builder父类BaseBuilder的属性之FeignCircuitBreakerInvocationHandler
		      return new ReflectiveFeign(handlersByName, invocationHandlerFactory, queryMapEncoder);
		    }
		}
	}
}

1.2.ReflectiveFeign之jdk动态代理

public class ReflectiveFeign extends Feign {
    @Override
    public <T> T newInstance(Target<T> target) {
        //解析当前Feign客户端所有方法,将每个方法抽象为 SynchronousMethodHandler
        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)));
          }
        }
        // FeignCircuitBreakerInvocationHandler:将目标方法抽象体SynchronousMethodHandler 跟 InvocationHandler建立绑定关系
        InvocationHandler handler = factory.create(target, methodToHandler);
        T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(),new Class<?>[] {target.type()}, handler);
        for (DefaultMethodHandler defaultMethodHandler : defaultMethodHandlers) {
          defaultMethodHandler.bindTo(proxy);
        }
        return proxy;
    }
}

?至此,利用JDK动态代理完成每个Feign客户端实例的创建。


2.域名调用方式之LazyTracingFeignClient


3.执行目标方法的代理过程


4.Feign & Builder关系

?

文章来源:https://blog.csdn.net/qq_36851469/article/details/135751724
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。