SpringCloudOpenFeign的核心组件总结

// Feign的最核心类,该对象负责设置Feign相关的绝大部分东西
public abstract class Feign {

    // 构建Feign的Builder对象
    public static Builder builder() {
        return new Builder();
    }

    // 生成配置的KEY
    public static String configKey(Class targetType, Method method) {
        StringBuilder builder = new StringBuilder();
        builder.append(targetType.getSimpleName());
        builder.append('#').append(method.getName()).append('(');
        for (Type param : method.getGenericParameterTypes()) {
            param = Types.resolve(targetType, targetType, param);
            builder.append(Types.getRawType(param).getSimpleName()).append(',');
        }
        if (method.getParameterTypes().length > 0) {
            builder.deleteCharAt(builder.length() - 1);
        }
        return builder.append(')').toString();
    }

    // 根据FeignClient的目标对象生成代理对象
    public abstract <T> T newInstance(Target<T> target);

    // 构建Feign的Builder对象
    public static class Builder extends BaseBuilder<Builder> {
        // 发送请求的客户端对象,默认使用HttpURLConnection发送请求
        // @TODO
        private Client client = new Client.Default(null, null);

        public <T> T target(Class<T> apiType, String url) {
            return target(new HardCodedTarget<>(apiType, url));
        }

        public <T> T target(Target<T> target) {
            Feign feign = this.build();
            return feign.newInstance(target);
        }

        // 构建Feign对象
        public Feign build() {
            // 增强当前类的字段信息
            super.enrich();
            // 创建响应的处理器对象,用来处理响应结果
            final ResponseHandler responseHandler = new ResponseHandler(logLevel, logger, decoder, errorDecoder, dismiss404, closeAfterDecode, responseInterceptor);
            // 创建生成方法处理器的工厂,方法处理器是用来执行方法的
            SynchronousMethodHandler.Factory<Object> methodHandlerFactory = new SynchronousMethodHandler.Factory(
                    client, retryer, requestInterceptors, responseHandler, logger, logLevel, propagationPolicy,
                    // 请求模板RequestTemplate的工厂解析器
                    // 通过该解析器可以解析到RequestTemplateFactory,然通过RequestTemplateFactory创建RequestTemplate对象
                    new RequestTemplateFactoryResolver(encoder, queryMapEncoder), options);
            // 创建基于反射的Feign对象
            return new ReflectiveFeign<>(contract, methodHandlerFactory, invocationHandlerFactory, () -> null);
        }
    }

}

// 构建Feign对象的Builder对象,内部包含Feing的所有核心组件
public abstract class BaseBuilder<B extends BaseBuilder<B>> {

    // 当前Builder对象
    private final B thisB;
    // 请求拦截器
    protected final List<RequestInterceptor> requestInterceptors = new ArrayList<>();
    // 响应拦截器 @TODO
    protected ResponseInterceptor responseInterceptor = ResponseInterceptor.DEFAULT;
    // Feign的日志级别
    protected Logger.Level logLevel = Logger.Level.NONE;
    // Contract 接口定义了如何根据 Java 接口的注解创建请求和解析响应
    // Contract 接口是 Feign 的一个核心接口,它可以自定义 Feign 客户端与服务端之间的契约规则,例如支持不同的注解风格、参数传递方式等
    // 通过实现自定义的 Contract 接口,可以更灵活地定制 Feign 客户端与服务端之间的通信行为
    // @TODO 看看下面的Default到底做了什么,这些都是Feign的核心组件
    protected Contract contract = new Contract.Default();
    // 重试机制
    protected Retryer retryer = new Retryer.Default();
    // 日志对象
    protected Logger logger = new NoOpLogger();
    // 编码(就是将参数解析为请求体)对象
    protected Encoder encoder = new Encoder.Default();
    // 解码对象(就是将响应体解码为返回值)
    protected Decoder decoder = new Decoder.Default();
    // 解码之后是否关闭资源
    protected boolean closeAfterDecode = true;
    // 对jpa请求参数转换为map的编码器
    protected QueryMapEncoder queryMapEncoder = new FieldQueryMapEncoder();
    // 异常解码器,该对象解码会得到一个异常对象
    protected ErrorDecoder errorDecoder = new ErrorDecoder.Default();
    // 请求的配置信息
    protected Options options = new Options();
    // 创建JDK动态代理中的InvocationHandler的对象
    protected InvocationHandlerFactory invocationHandlerFactory = new InvocationHandlerFactory.Default();
    // 是否应该解码404而不是抛出feigexception,默认为false
    // 如果为true,404也会返回对应的结果
    protected boolean dismiss404;
    // 该对象是用于设定Feign异常的传播策略
    protected ExceptionPropagationPolicy propagationPolicy = NONE;
    // 该对象是用于将以上描述的组件进行增强的接口
    // 该接口的定义: A enrich (A a){return a;},给你指定参数,让你增强,返回增强后的组件
    protected List<Capability> capabilities = new ArrayList<>();

    public BaseBuilder() {
        thisB = (B) this;
    }

    // 增强当前类的字段信息
    public B enrich() {
        // 如果不存在增强器,不处理
        if (capabilities.isEmpty()) {
            return thisB;
        }
        // 获取到当前类的所有字段信息
        this.getFieldsToEnrich().forEach(field -> {
            field.setAccessible(true);
            // 获取原来的值
            final Object originalValue = field.get(thisB);
            // 增强的值
            final Object enriched;
            // 如果是List
            if (originalValue instanceof List) {
                // 获取到泛型信息
                Type ownerType = ((ParameterizedType) field.getGenericType()).getActualTypeArguments()[0];
                // 对List的每一个元素进行增强
                enriched = ((List) originalValue).stream()
                        .map(value -> Capability.enrich(value, (Class<?>) ownerType, capabilities))
                        .collect(Collectors.toList());
            } else {
                // 单独对某个字段增强,方法定义: A aa(A a){ return a;}
                enriched = Capability.enrich(originalValue, field.getType(), capabilities);
            }
            // 将字段变成增强后的字段
            field.set(thisB, enriched);
        });
        return thisB;
    }

    // 获取需要被增强的字段
    public List<Field> getFieldsToEnrich() {
        return Util.allFields(getClass())
                .stream()
                .filter(field -> !field.isSynthetic())
                .filter(field -> !Objects.equals(field.getName(), "capabilities"))
                .filter(field -> !Objects.equals(field.getName(), "thisB"))
                .filter(field -> !field.getType().isPrimitive())
                .filter(field -> !field.getType().isEnum())
                .collect(Collectors.toList());
    }


}

// 对Feign接口进行自定义的Bean
@FunctionalInterface
public interface FeignBuilderCustomizer {
    void customize(Feign.Builder builder);
}

// Feign客户端的配置类
public interface FeignClientConfigurer {
    // 标注的@FeignClient是否是主要的@Bean,因为在存在熔断的时候,FeignClient可能存在兜底同类型的Bean,因此,默认将@FeignClent标注的接口作为主要的Bean
    // 可以通过该配置进行修改
    default boolean primary() {
        return true;
    }

    // 对于每一个FeignClient,都有一个独立的ApplicationContext对象,会继承(父容器)全局的ApplicationContext
    // 如果不想继承全局容器中的Bean信息,可以关闭
    default boolean inheritParentConfiguration() {
        return true;
    }
}

// Feign的日志组件,具体依赖的还是对应的日志实现(Slf4j...)
// 在Feign中,日志都是有该对象打印
public abstract class Logger {
    protected abstract void log(String configKey, String format, Object... args);

    protected boolean shouldLogRequestHeader(String header) {
        return true;
    }

    protected boolean shouldLogResponseHeader(String header) {
        return true;
    }

    // 日志级别,对于每一个FeignClient,都会存在一个Logger对象,并且,Logger对象的日志级别会从Spring容器中获取Level的Bean对象它的日志级别
    // 默认为NONE,因为,如果要设置FeignClient的日志级别,可以注入Level的Bean对象
    // 还有其他方式,可以使用配置文件属性
    public enum Level {
        // 不记录日志
        NONE,
        // 只记录请求方法和URL以及响应状态代码和执行时间
        BASIC,
        // 记录基本信息以及请求和响应头。
        HEADERS,
        // 记录请求和响应的报头、正文和元数据。
        FULL
    }
}

// 重试机制接口
public interface Retryer extends Cloneable {
    // 继续执行
    void continueOrPropagate(RetryableException e);

    // 拷贝属性
    Retryer clone();

    // 默认实现,就是记录重试次数,不执行业务逻辑,需要自己控制业务逻辑的重试
    class Default implements Retryer {
        // 重试的最大次数(包括第一次)
        private final int maxAttempts;
        // 多久之后开启重试机制
        private final long period;
        // 每隔多久重试一次
        private final long maxPeriod;
        // 已执行次数
        int attempt;
        // 重试过程的休眠时间
        long sleptForMillis;

        // 100ms之后开启重试机制,每隔1秒重试一次,总共执行5次(1(默认调用) + n-1(重试次数))
        public Default() {
            this(100, SECONDS.toMillis(1), 5);
        }

        public Default(long period, long maxPeriod, int maxAttempts) {
            this.period = period;
            this.maxPeriod = maxPeriod;
            this.maxAttempts = maxAttempts;
            this.attempt = 1;
        }

        // 可用于测试
        protected long currentTimeMillis() {
            return System.currentTimeMillis();
        }

        // 继续重试
        public void continueOrPropagate(RetryableException e) {
            // 已执行次数大于等于最大执行次数,抛出异常
            if (attempt++ >= maxAttempts) {
                throw e;
            }
            // 记录重试次数
            long interval;
            // 存在下一次的执行时间
            if (e.retryAfter() != null) {
                // 记录时间间隔
                interval = e.retryAfter().getTime() - currentTimeMillis();
                if (interval > maxPeriod) {
                    interval = maxPeriod;
                }
                if (interval < 0) {
                    return;
                }
            } else {
                interval = nextMaxInterval();
            }
            try {
                // 休眠到执行的时间间隔再执行
                Thread.sleep(interval);
            } catch (InterruptedException ignored) {
                Thread.currentThread().interrupt();
                throw e;
            }
            // 记录休眠时间
            sleptForMillis += interval;
        }

        // 计算下一次的执行时间间隔
        public long nextMaxInterval() {
            long interval = (long) (period * Math.pow(1.5, attempt - 1));
            return interval > maxPeriod ? maxPeriod : interval;
        }

        @Override
        public Retryer clone() {
            return new Default(period, maxPeriod, maxAttempts);
        }
    }

    // 禁止重试机制
    Retryer NEVER_RETRY = new Retryer() {

        @Override
        public void continueOrPropagate(RetryableException e) {
            throw e;
        }

        @Override
        public Retryer clone() {
            return this;
        }
    };
}

// 错误解码器,就是处理错误的响应结果的处理器(例如处理404,400)
// 也就是如何返回指定的异常通知下一步需要做什么,例如: 抛出RetryableException表示继续发起重试
public interface ErrorDecoder {
    // 方法签名,响应对象
    public Exception decode(String methodKey, Response response);

    // 默认的实现
    public class Default implements ErrorDecoder {
        // 重试之后的解码器
        private final RetryAfterDecoder retryAfterDecoder = new RetryAfterDecoder();
        // 响应体的最大字节长度
        private Integer maxBodyBytesLength;
        // 响应体的最大字符
        private Integer maxBodyCharsLength;

        public Default() {
            this.maxBodyBytesLength = null;
            this.maxBodyCharsLength = null;
        }

        public Default(Integer maxBodyBytesLength, Integer maxBodyCharsLength) {
            this.maxBodyBytesLength = maxBodyBytesLength;
            this.maxBodyCharsLength = maxBodyCharsLength;
        }

        @Override
        public Exception decode(String methodKey, Response response) {
            // 根据不同的错误状态码进行相应的处理,返回一个FeignException对象
            FeignException exception = errorStatus(methodKey, response, maxBodyBytesLength, maxBodyCharsLength);
            // 从请求头获取下一次重试的时间
            Date retryAfter = retryAfterDecoder.apply(firstOrNull(response.headers(), RETRY_AFTER));
            // 如果需要重试,抛出重试异常,这样就会继续发起重试
            if (retryAfter != null) {
                return new RetryableException(response.status(), exception.getMessage(), response.request().httpMethod(), exception, retryAfter, response.request());
            }
            // 如果重试完成,则抛出FeignException
            return exception;
        }
    }


    // 下次一重试时间的解码器
    static class RetryAfterDecoder {

        static final DateFormat RFC822_FORMAT = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss 'GMT'", US);
        private final DateFormat rfc822Format;

        RetryAfterDecoder() {
            this(RFC822_FORMAT);
        }

        RetryAfterDecoder(DateFormat rfc822Format) {
            this.rfc822Format = checkNotNull(rfc822Format, "rfc822Format");
        }

        protected long currentTimeMillis() {
            return System.currentTimeMillis();
        }

        // 获取下一次的重试时间
        public Date apply(String retryAfter) {
            if (retryAfter == null) {
                return null;
            }
            if (retryAfter.matches("^[0-9]+\\.?0*$")) {
                retryAfter = retryAfter.replaceAll("\\.0*$", "");
                long deltaMillis = SECONDS.toMillis(Long.parseLong(retryAfter));
                return new Date(currentTimeMillis() + deltaMillis);
            }
            return rfc822Format.parse(retryAfter);
        }
    }
}

// 创建ErrorDecoder的工厂类
public interface FeignErrorDecoderFactory {
    ErrorDecoder create(Class<?> type);
}

// Feign发送请求的核心对象
public class Request {
    // 请求方式
    private final HttpMethod httpMethod;
    // 请求url
    private final String url;
    // 请求头
    private final Map<String, Collection<String>> headers;
    // 请求体
    private final Body body;
    // 发送请求的模板对象,它负责组装url,请求参数,请求头等一系列请求相关的数据,所以才成为请求模板类
    private final RequestTemplate requestTemplate;
    // 请求协议
    private final ProtocolVersion protocolVersion;

    // 请求方法
    public enum HttpMethod {
        GET, HEAD, POST(true), PUT(true), DELETE, CONNECT, OPTIONS, TRACE, PATCH(true);
        private final boolean withBody;
    }

    // 创建Request对象
    public static Request create(HttpMethod httpMethod, String url, Map<String, Collection<String>> headers, Body body, RequestTemplate requestTemplate) {
        return new Request(httpMethod, url, headers, body, requestTemplate);
    }

    // 请求的属性配置
    public static class Options {
        private final long connectTimeout;
        private final TimeUnit connectTimeoutUnit;
        private final long readTimeout;
        private final TimeUnit readTimeoutUnit;
        private final boolean followRedirects;
    }

    public static class Body implements Serializable {
        private transient Charset encoding;
        private byte[] data;
    }
}

// 请求拦截器,可以对请求数据进行加工
public interface RequestInterceptor {

    // 每个请求都会被调用
    void apply(RequestTemplate template);

    // Basic认证拦截器,添加Basic请求头
    public class BasicAuthRequestInterceptor implements RequestInterceptor {
        // 请求头的值
        private final String headerValue;

        public BasicAuthRequestInterceptor(String username, String password) {
            this(username, password, ISO_8859_1);
        }

        @Override
        public void apply(RequestTemplate template) {
            template.header("Authorization", headerValue);
        }
    }

}

// 响应拦截器,同时进行解码操作,具体的操作依赖于解码器
public interface ResponseInterceptor {
    // 默认的实现
    ResponseInterceptor DEFAULT = (invocationContext) -> {
        invocationContext.proceed()
    }

    // 解码操作
    Object aroundDecode(InvocationContext invocationContext) throws IOException;
}

// 执行的上下文对象
public class InvocationContext {
    // 解码器
    private final Decoder decoder;
    // 返回值类型
    private final Type returnType;
    // 响应体
    private final Response response;

    public Object proceed() {
        // 调用解码器进行解码
        return decoder.decode(response, returnType);
    }
}

// 将请求参数对象转换为map,然后通过query参数发送请求
public interface QueryMapEncoder {

    Map<String, Object> encode(Object object);

    public class Default extends FieldQueryMapEncoder {
    }

    public class FieldQueryMapEncoder implements QueryMapEncoder {

        private final Map<Class<?>, ObjectParamMetadata> classToMetadata = new ConcurrentHashMap<>();

        @Override
        public Map<String, Object> encode(Object object) throws EncodeException {
            if (object == null) {
                return Collections.emptyMap();
            }
            // 对象所有字段的元信息,也就是获取该对象的所有字段信息
            ObjectParamMetadata metadata = classToMetadata.computeIfAbsent(object.getClass(), ObjectParamMetadata::parseObjectType);

            return metadata.objectFields.stream()
                    // 将字段封装成映射关系 Field -> Optional.ofNullable(FieldValue)
                    .map(field -> this.FieldValuePair(object, field))
                    .filter(fieldObjectPair -> fieldObjectPair.right.isPresent())
                    // 转换为map信息
                    .collect(Collectors.toMap(
                            // 优先获取@Param参数的字段名,不存在则获取字段名
                            this::fieldName,
                            // 值为该字段的值
                            fieldObjectPair -> fieldObjectPair.right.get()));

        }

        // 优先获取@Param参数的字段名,不存在则获取字段名
        private String fieldName(Pair<Field, Optional<Object>> pair) {
            Param alias = pair.left.getAnnotation(Param.class);
            return alias != null ? alias.value() : pair.left.getName();
        }

        // 对象所有字段的元信息
        private static class ObjectParamMetadata {

            // 该对象的所有字段
            private final List<Field> objectFields;

            private ObjectParamMetadata(List<Field> objectFields) {
                this.objectFields = Collections.unmodifiableList(objectFields);
            }

            private static ObjectParamMetadata parseObjectType(Class<?> type) {
                List<Field> allFields = new ArrayList();

                // 保存该类已经所有父类的所有字段信息
                for (Class currentClass = type; currentClass != null; currentClass = currentClass.getSuperclass()) {
                    Collections.addAll(allFields, currentClass.getDeclaredFields());
                }
                return new ObjectParamMetadata(allFields.stream()
                        .filter(field -> !field.isSynthetic())
                        .peek(field -> field.setAccessible(true))
                        .collect(Collectors.toList()));
            }
        }
    }
}

// 异常传播策略,在请求过程中出现异常该如何处理
public class ExceptionPropagationPolicy {
    NONE,UNWRAP

    // 使用该元素的伪代码
    public void invoke() {
        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 {
                    // 默认返回包装的RetryableException
                    throw th;
                }
            }
        }
    }
}

// 对Feign组件的增强器
public interface Capability {
    // 只选几个显示,增强发送请求的客户端
    default Client enrich(Client client) {
        return client;
    }

    // 增强重试机制
    default Retryer enrich(Retryer retryer) {
        return retryer;
    }

    // 增强编码器
    default Encoder enrich(Encoder encoder) {
        return encoder;
    }

    // 增强解码器
    default Decoder enrich(Decoder decoder) {
        return decoder;
    }


    // 缓存的增强器,对目标方法进行缓存逻辑
    public class CachingCapability implements Capability {

        // Spring的缓存拦截器
        private final CacheInterceptor cacheInterceptor;

        public CachingCapability(CacheInterceptor cacheInterceptor) {
            this.cacheInterceptor = cacheInterceptor;
        }

        // 对生成JDK代理对象的InvocationHandler进行增强
        @Override
        public InvocationHandlerFactory enrich(InvocationHandlerFactory invocationHandlerFactory) {
            return new FeignCachingInvocationHandlerFactory(invocationHandlerFactory, cacheInterceptor);
        }
    }
}

// 编码器,将参数编码为请求体的类
public interface Encoder {
    // 通配符标识
    Type MAP_STRING_WILDCARD = Util.MAP_STRING_WILDCARD;

    // 编码
    void encode(Object object, Type bodyType, RequestTemplate template) throws EncodeException;

    // 默认的实现,只支持String和byte[]的编码
    public class Default implements Encoder {

        @Override
        public void encode(Object object, Type bodyType, RequestTemplate template) {
            // 如果请求体类型为String
            if (bodyType == String.class) {
                // 设置String类型的请求体
                template.body(object.toString());
            }
            // byte数组
            else if (bodyType == byte[].class) {
                template.body((byte[]) object, null);
            }
            // 如果不是上面两种,抛出异常,默认的编码器只支持这两种
            else if (object != null) {
                throw new EncodeException(format("%s is not a type supported by this encoder.", object.getClass()));
            }
        }
    }

    // 基于Spring的实现
    public class SpringEncoder implements Encoder {
        // Spring表单的编码器
        private final SpringFormEncoder springFormEncoder;
        // Spring的消息转换器,将请求和响应数据进行读取和写入的核心类
        private final ObjectFactory<HttpMessageConverters> messageConverters;
        // Feign编码相关的配置信息
        private final FeignEncoderProperties encoderProperties;
        // 对HttpMessageConverters进行自定义的类
        private final ObjectProvider<HttpMessageConverterCustomizer> customizers;

        public SpringEncoder(ObjectFactory<HttpMessageConverters> messageConverters) {
            this(new SpringFormEncoder(), messageConverters, new FeignEncoderProperties(), new EmptyObjectProvider<>());
        }

        public SpringEncoder(SpringFormEncoder springFormEncoder, ObjectFactory<HttpMessageConverters> messageConverters, FeignEncoderProperties encoderProperties, ObjectProvider<HttpMessageConverterCustomizer> customizers) {
            this.springFormEncoder = springFormEncoder;
            this.messageConverters = messageConverters;
            this.encoderProperties = encoderProperties;
            this.customizers = customizers;
        }

        @Override
        public void encode(Object requestBody, Type bodyType, RequestTemplate request) throws EncodeException {
            // template.body(conversionService.convert(object, String.class));
            if (requestBody != null) {
                // 获取请求头,获取请求体类型
                Collection<String> contentTypes = request.headers().get(HttpEncoding.CONTENT_TYPE);

                MediaType requestContentType = null;
                if (contentTypes != null && !contentTypes.isEmpty()) {
                    String type = contentTypes.iterator().next();
                    requestContentType = MediaType.valueOf(type);
                }
                // 是否是表单类型的请求体
                if (isFormRelatedContentType(requestContentType)) {
                    // 使用表单的编码器进行编码,解析文件,字段等等
                    springFormEncoder.encode(requestBody, bodyType, request);
                    return;
                }
                // 使用消息转换器进行编码
                this.encodeWithMessageConverter(requestBody, bodyType, request, requestContentType);
            }
        }

        // 使用消息转换器进行编码
        private void encodeWithMessageConverter(Object requestBody, Type bodyType, RequestTemplate request, MediaType requestContentType) {
            // 获取所有消息转换器
            List<HttpMessageConverter<?>> converters = messageConverters.getObject().getConverters();
            // 先执行所有的自定义类
            customizers.forEach(customizer -> customizer.accept(converters));
            // 遍历所有的消息转换器
            for (HttpMessageConverter messageConverter : converters) {
                // 判断是否支持写入该类型的数据,如果支持,则写入
                FeignOutputMessage outputMessage = checkAndWrite(requestBody, requestContentType, messageConverter, request);
                // 如果不为空,表示支持写入
                if (outputMessage != null) {
                    // 请求请求头
                    request.headers(null);
                    // 添加新的请求头
                    request.headers(new LinkedHashMap<>(outputMessage.getHeaders()));
                    // ... 其他操作
                    // 最终将数据转换为字节数组传递
                    request.body(outputMessage.getOutputStream().toByteArray(), charset);
                    return;
                }
            }
            // 如果没有消息转换器可以写入,抛出异常
            throw new EncodeException(message);
        }

        @SuppressWarnings("unchecked")
        private FeignOutputMessage checkAndWrite(Object body, MediaType contentType, HttpMessageConverter converter, RequestTemplate request) throws IOException {
            // 判断是否支持写该类型的数据
            if (!converter.canWrite(body.getClass(), contentType)) {
                return null;
            }
            // 打印写之前的日志
            logBeforeWrite(body, contentType, converter);
            FeignOutputMessage outputMessage = new FeignOutputMessage(request);
            // 开始写入
            converter.write(body, contentType, outputMessage);
            return outputMessage;
        }
    }
}

// 解码器,将响应体解码为返回值的类
public interface Decoder {
    Object decode(Response response, Type type) throws IOException, DecodeException, FeignException;

    // 默认实现,支持字节数组和String类型的解码
    public class Default extends StringDecoder {

        @Override
        public Object decode(Response response, Type type) throws IOException {
            // 非正常状态,返回空对象
            if (response.status() == 404 || response.status() == 204) {
                return Util.emptyValueOf(type);
            }
            // 没有响应体,不需要解码
            if (response.body() == null) {
                return null;
            }
            // 如果是字符数组,转换为字符数据
            if (byte[].class.equals(type)) {
                return Util.toByteArray(response.body().asInputStream());
            }
            // 转换为String
            return super.decode(response, type);
        }
    }

    // 将响应体转换为String的解码器
    public class StringDecoder implements Decoder {

        @Override
        public Object decode(Response response, Type type) throws IOException {
            // 获取响应体
            Response.Body body = response.body();
            // 非正常状态,不处理
            if (response.status() == 404 || response.status() == 204 || body == null) {
                return null;
            }
            // 将响应体转为String类型
            if (String.class.equals(type)) {
                return Util.toString(body.asReader(Util.UTF_8));
            }
            // 不是String类型,抛出异常
            throw new DecodeException(response.status(), format("%s is not a type supported by this decoder.", type), response.request());

        }
    }

    // 基于Spring的实现
    public class SpringDecoder implements Decoder {

        // Spring的消息转换器,将请求和响应数据进行读取和写入的核心类
        private final ObjectFactory<HttpMessageConverters> messageConverters;
        // 对HttpMessageConverters进行自定义的类
        private final ObjectProvider<HttpMessageConverterCustomizer> customizers;

        public SpringDecoder(ObjectFactory<HttpMessageConverters> messageConverters, ObjectProvider<HttpMessageConverterCustomizer> customizers) {
            this.messageConverters = messageConverters;
            this.customizers = customizers;
        }

        @Override
        public Object decode(final Response response, Type type) throws IOException, FeignException {
            // 处理任意类或者通配符或者泛型参数
            if (type instanceof Class || type instanceof ParameterizedType || type instanceof WildcardType) {
                // 获取所有的消息转换器
                List<HttpMessageConverter<?>> converters = messageConverters.getObject().getConverters();
                // 先执行所有的自定义类
                customizers.forEach(customizer -> customizer.accept(converters));
                // 创建包装类
                IntrospectingClientHttpResponse responseWrapper = new IntrospectingClientHttpResponse(new FeignResponseAdapter(response));
                // 如果没有响应体,不需要解码
                if (!responseWrapper.hasMessageBody() || responseWrapper.hasEmptyMessageBody()) {
                    return null;
                }
                // 获取响应体类型
                MediaType contentType = getContentType(responseWrapper);
                // 遍历所有的消息转换器
                for (HttpMessageConverter<?> messageConverter : converters) {
                    if (messageConverter instanceof GenericHttpMessageConverter genericMessageConverter) {
                        // 判断消息转换器是否可以读取响应体的内容,如果可以读取,就读取成指定的返回值类型
                        if (genericMessageConverter.canRead(this.responseType, null, contentType)) {
                            return (T) genericMessageConverter.read(this.responseType, null, responseWrapper);
                        }
                    }
                }
                // 没有消息转换器可以读取该消息,抛出异常
                throw new UnknownContentTypeException(this.responseType, contentType, responseWrapper.getStatusCode(), responseWrapper.getStatusText(), responseWrapper.getHeaders(), getResponseBody(responseWrapper));

            }
            // 不支持的类型
            throw new DecodeException(response.status(), "type is not an instance of Class or ParameterizedType: " + type, response.request());
        }
    }
}

// 参数标注注解
@Target({PARAMETER, FIELD, METHOD})
public @interface Param {
    // 参数名称
    String value() default "";

    // 参数扩展器,因为最终参数都需要转换为String或者byte[],然后在发送请求
    // 所以需要一个扩展器,将参数转换为String
    Class<? extends Expander> expander() default ToStringExpander.class;

    boolean encoded() default false;

    // 参数扩展器,因为最终参数都需要转换为String或者byte[],然后在发送请求
    // 所以需要一个扩展器,将参数转换为String
    interface Expander {
        // 将参数转换为String
        String expand(Object value);
    }

    public class ToStringExpander implements Expander {

        @Override
        public String expand(Object value) {
            return value.toString();
        }
    }
}

// 用于解析类中的所有方法的元数据信息,包括类注解,方法注解,参数注解
public interface Contract {

    // 解析指定类的所有方法元数据,并对方法或者参数进行一些校验
    List<MethodMetadata> parseAndValidateMetadata(Class<?> targetType);

    // 该类就是验证参数的是否符合规则,并且保存各个参数的细节信息,例如该参数是否为URI类型,是否为HeaderMap,获取QueryMap参数,都会记录都方法的元数据对象中
    // 具体处理类中,方法中,参数的注解的逻辑都是抽象的
    abstract class BaseContract implements Contract {

        @Override
        public List<MethodMetadata> parseAndValidateMetadata(Class<?> targetType) {
            // 参数校验
            // 该类不能存在泛型
            checkState(targetType.getTypeParameters().length == 0, "Parameterized types unsupported: %s", targetType.getSimpleName());
            // 该类最多继承或实现一个接口
            checkState(targetType.getInterfaces().length <= 1, "Only single inheritance supported: %s", targetType.getSimpleName());

            // 最终解析到该类对应的所有方法的元数据信息
            final Map<String, MethodMetadata> result = new LinkedHashMap<String, MethodMetadata>();
            // 遍历指定类的所有方法
            for (final Method method : targetType.getMethods()) {
                // 忽略Object中的方法,以及static方法,以及接口的默认方法
                if (method.getDeclaringClass() == Object.class || (method.getModifiers() & Modifier.STATIC) != 0 || Util.isDefault(method)) {
                    continue;
                }
                // 解析类中指定方法的元数据
                final MethodMetadata metadata = this.parseAndValidateMetadata(targetType, method);
                // 如果已经解析过,并且返回值类型不一样,覆盖原来的
                if (result.containsKey(metadata.configKey())) {
                    MethodMetadata existingMetadata = result.get(metadata.configKey());
                    Type existingReturnType = existingMetadata.returnType();
                    Type overridingReturnType = metadata.returnType();
                    Type resolvedType = Types.resolveReturnType(existingReturnType, overridingReturnType);
                    if (resolvedType.equals(overridingReturnType)) {
                        result.put(metadata.configKey(), metadata);
                    }
                    continue;
                }
                // 保存该方法的元数据
                result.put(metadata.configKey(), metadata);
            }
            return new ArrayList<>(result.values());
        }

        // 解析每一个方法元数据
        protected MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
            // 方法的元数据对象
            final MethodMetadata data = new MethodMetadata();
            // 设置目标类型
            data.targetType(targetType);
            // 设置方法对象
            data.method(method);
            // 设置方法的返回类型
            data.returnType(Types.resolve(targetType, targetType, method.getGenericReturnType()));
            // 设置方法签名
            data.configKey(Feign.configKey(targetType, method));
            // 设置是否总是编码请求体
            if (AlwaysEncodeBodyContract.class.isAssignableFrom(this.getClass())) {
                data.alwaysEncodeBody(true);
            }
            // 是否存在实现或者继承的接口
            if (targetType.getInterfaces().length == 1) {
                // 处理接口中的注解
                processAnnotationOnClass(data, targetType.getInterfaces()[0]);
            }
            // 再处理类中的注解
            processAnnotationOnClass(data, targetType);

            // 获取方法中的所有注解
            for (final Annotation methodAnnotation : method.getAnnotations()) {
                // 处理方法中的注解
                processAnnotationOnMethod(data, methodAnnotation, method);
            }
            // 如果标记了忽略该方法,则直接返回,否在继续处理方法参数
            if (data.isIgnored()) {
                return data;
            }
            // 如果方法没有标注请求方式,例如@GetMapping等等,抛出异常
            checkState(data.template().method() != null, "Method %s not annotated with HTTP method type (ex. GET, POST)%s", data.configKey(), data.warnings());
            // 获取方法的参数类型
            Class<?>[] parameterTypes = method.getParameterTypes();
            // 获取方法的泛型参数类型
            Type[] genericParameterTypes = method.getGenericParameterTypes();
            // 获取方法的参数注解
            Annotation[][] parameterAnnotations = method.getParameterAnnotations();
            int count = parameterAnnotations.length;
            // 遍历所有的参数注解
            for (int i = 0; i < count; i++) {
                // 是否是http相关注解,例如: @RequestParam,@PathVariable,@CookieValue等等
                boolean isHttpAnnotation = false;
                // 如果存在注解信息
                if (parameterAnnotations[i] != null) {
                    // 处理参数中的注解,返回是否是Http注解的标识
                    isHttpAnnotation = processAnnotationsOnParameter(data, parameterAnnotations[i], i);
                }
                // 如果是http注解
                if (isHttpAnnotation) {
                    // 设置该参数需要被忽略
                    data.ignoreParamater(i);
                }
                // 如果参数类型为URI
                if (parameterTypes[i] == URI.class) {
                    // 设置该参数下标为存储的是URI
                    data.urlIndex(i);
                }
                // 如果不是Http相关注解,并且不是请求相关参数配置
                else if (!isHttpAnnotation && !Request.Options.class.isAssignableFrom(parameterTypes[i])) {
                    // 如果该参数被处理过
                    if (data.isAlreadyProcessed(i)) {
                        // 校验没有表单参数,并且没有标注请求体参数,如果有,抛出异常
                        checkState(data.formParams().isEmpty() || data.bodyIndex() == null, "Body parameters cannot be used with form parameters.%s", data.warnings());
                    }
                    // 如果未标记总是需要编码请求体,将指定参数编码为请求体
                    else if (!data.alwaysEncodeBody()) {
                        // 校验没有表单参数,并且没有标注请求体参数,如果有,抛出异常
                        checkState(data.formParams().isEmpty(), "Body parameters cannot be used with form parameters.%s", data.warnings());
                        checkState(data.bodyIndex() == null, "Method has too many Body parameters: %s%s", method, data.warnings());
                        // 标记该参数下标存储的是一个body参数
                        data.bodyIndex(i);
                        data.bodyType(Types.resolve(targetType, targetType, genericParameterTypes[i]));
                    }
                }
            }
            // 如果方法元数据已经保存了参数为Map,并且为请求头的索引下标
            if (data.headerMapIndex() != null) {
                // 验证参数的Key
                if (Map.class.isAssignableFrom(parameterTypes[data.headerMapIndex()])) {
                    checkMapKeys("HeaderMap", genericParameterTypes[data.headerMapIndex()]);
                }
            }
            // 如果方法元数据已经保存了参数为Map,并且为查询参数的索引下标
            if (data.queryMapIndex() != null) {
                if (Map.class.isAssignableFrom(parameterTypes[data.queryMapIndex()])) {
                    // 验证参数的Key
                    checkMapKeys("QueryMap", genericParameterTypes[data.queryMapIndex()]);
                }
            }
            return data;
        }

        // 解析类中的注解信息
        protected abstract void processAnnotationOnClass(MethodMetadata data, Class<?> clz);

        // 解析方法中的注解信息
        protected abstract void processAnnotationOnMethod(MethodMetadata data, Annotation annotation, Method method);

        // 解析参数中的注解信息
        protected abstract boolean processAnnotationsOnParameter(MethodMetadata data, Annotation[] annotations, int paramIndex);


        /**
         * 保存所有的参数名称, 参数索引 -> 参数名称的映射关系,保存到方法元数据中
         *
         * @param data  方法的元数据对象
         * @param name  方法参数名
         * @param index 方法参数的下标
         */
        protected void nameParam(MethodMetadata data, String name, int index) {
            Collection<String> names = data.indexToName().containsKey(index) ? data.indexToName().get(index) : new ArrayList<String>();
            names.add(name);
            data.indexToName().put(i, names);
        }
    }

    // Feign默认的方法注解实现
    class Default extends DeclarativeContract {

        // @RequestLine的正则
        // @RequestLine("GET /api/resource?ids={ids}")
        static final Pattern REQUEST_LINE_PATTERN = Pattern.compile("^([A-Z]+)[ ]*(.*)$");

        public Default() {
            // 注册标注在类中的@Headers注解的处理器
            super.registerClassAnnotation(Headers.class,
                    // @Headers注解的处理逻辑
                    (header, data) -> {
                        // 获取到注解值
                        String[] headersOnType = header.value();
                        // 转换为Map
                        Map<String, Collection<String>> headers = toMap(headersOnType);
                        // 保存原有的header
                        headers.putAll(data.template().headers());
                        // 清空所有的header
                        data.template().headers(null);
                        // 将注解中的header+原有的header组合设置到请求模版对象中
                        data.template().headers(headers);
                    });
            // 注册标注在方法中的@RequestLine注解的处理器
            super.registerMethodAnnotation(RequestLine.class,
                    // 该@RequestLine注解的处理器
                    (ann, data) -> {
                        // 获取注解值
                        String requestLine = ann.value();
                        // 获取匹配器
                        Matcher requestLineMatcher = REQUEST_LINE_PATTERN.matcher(requestLine);
                        // @RequestLine("GET /api/resource?ids={ids}")
                        // 不符合规则,抛出异常
                        if (!requestLineMatcher.find()) {
                            throw new IllegalStateException(String.format("RequestLine annotation didn't start with an HTTP verb on method %s", data.configKey()));
                        } else {
                            // 设置方法的请求方式
                            data.template().method(HttpMethod.valueOf(requestLineMatcher.group(1)));
                            // 设置方法的请求路径
                            data.template().uri(requestLineMatcher.group(2));
                        }
                        // 设置其他的
                        data.template().decodeSlash(ann.decodeSlash());
                        data.template().collectionFormat(ann.collectionFormat());
                    });
            // 注册标注在方法中的@Body注解的处理器
            super.registerMethodAnnotation(Body.class,
                    (ann, data) -> {
                        // 获取body
                        String body = ann.value();
                        checkState(emptyToNull(body) != null, "Body annotation was empty on method %s.", data.configKey());
                        // 设置body到请求模版对象中,如果存在{},则要解析模版
                        if (body.indexOf('{') == -1) {
                            data.template().body(body);
                        } else {
                            data.template().bodyTemplate(body);
                        }
                    });
            // 注册标注在方法中的@Headers注解的处理器
            super.registerMethodAnnotation(Headers.class,
                    (header, data) -> {
                        // 获取header的值
                        String[] headersOnMethod = header.value();
                        // 直接将header转换为map,设置到请求模板中
                        data.template().headers(toMap(headersOnMethod));
                    });
            // 注册标注在参数中的@Param注解的处理器
            super.registerParameterAnnotation(Param.class,
                    (paramAnnotation, data, paramIndex) -> {
                        // 获取注解标注的参数名称
                        String annotationName = paramAnnotation.value();
                        // 获取参数对象
                        Parameter parameter = data.method().getParameters()[paramIndex];
                        String name;
                        // 解析名称,优先取注解中的名称,再去参数本身的名称
                        if (emptyToNull(annotationName) == null && parameter.isNamePresent()) {
                            name = parameter.getName();
                        } else {
                            name = annotationName;
                        }
                        // 保存参数名称, 参数索引 -> 参数名称的映射关系,保存到方法元数据中
                        this.nameParam(data, name, paramIndex);
                        // 获取展开器,将指定值转换为String类型的类
                        Class<? extends Param.Expander> expander = paramAnnotation.expander();
                        // 如果不是ToStringExpander展开器
                        if (expander != Param.ToStringExpander.class) {
                            // 保存该参数的下标以及将该参数转为String类型的展开器的映射关系
                            data.indexToExpanderClass().put(paramIndex, expander);
                        }
                        // 如果url变量,请求头,请求参数中包含该名称
                        if (!data.template().hasRequestVariable(name)) {
                            // 将该名称添加到表单参数中
                            data.formParams().add(name);
                        }
                    });
            // 注册标注在参数中的@QueryMap注解的处理器
            super.registerParameterAnnotation(QueryMap.class,
                    (queryMap, data, paramIndex) -> {
                        // 将该参数设置为是一个queryMap,最终会将它设置到query参数中
                        data.queryMapIndex(paramIndex);
                    });
            // 注册标注在参数中的@HeaderMap注解的处理器
            super.registerParameterAnnotation(HeaderMap.class,
                    (queryMap, data, paramIndex) -> {
                        // 将该参数设置为是一个headerMap,最终会将它设置到请求头中
                        data.headerMapIndex(paramIndex);
                    });
        }
    }

    // 声明式的类方法处理器,根据类中注解,方法中的注解,参数中的注解进行处理
    public abstract class DeclarativeContract extends BaseContract {
        // 处理类中注解的处理器
        private final List<GuardedAnnotationProcessor> classAnnotationProcessors = new ArrayList<>();
        // 处理方法中注解的处理器
        private final List<GuardedAnnotationProcessor> methodAnnotationProcessors = new ArrayList<>();
        // 处理参数注解的处理器
        private final Map<Class<Annotation>, DeclarativeContract.ParameterAnnotationProcessor<Annotation>> parameterAnnotationProcessors = new HashMap<>();


        @Override
        public final List<MethodMetadata> parseAndValidateMetadata(Class<?> targetType) {
            // any implementations must register processors
            return super.parseAndValidateMetadata(targetType);
        }

        // 处理类中的注解
        @Override
        protected final void processAnnotationOnClass(MethodMetadata data, Class<?> targetType) {
            // 获取类中的所有的注解信息
            final List<GuardedAnnotationProcessor> processors = Arrays.stream(targetType.getAnnotations())
                    // 遍历每一个注解,并且找到类处理器中能处理该注解的所有处理器
                    .flatMap(annotation -> classAnnotationProcessors.stream()
                            .filter(processor -> processor.test(annotation)))
                    // 将符合条件的所有类注解处理器保存
                    .collect(Collectors.toList());

            // 如果存在可以处理类中注解的处理器
            if (!processors.isEmpty()) {
                // 执行可以处理这些注解的处理器,解析类注解
                Arrays.stream(targetType.getAnnotations())
                        .forEach(annotation -> processors.stream()
                                .filter(processor -> processor.test(annotation))
                                .forEach(processor -> processor.process(annotation, data)));
            }
            // 不存在任何类注解相关的处理器
            else {
                // 记录警告信息
                if (targetType.getAnnotations().length == 0) {
                    data.addWarning(String.format("Class %s has no annotations, it may affect contract %s", targetType.getSimpleName(), getClass().getSimpleName()));
                } else {
                    data.addWarning(String.format("Class %s has annotations %s that are not used by contract %s", targetType.getSimpleName(), Arrays.stream(targetType.getAnnotations()).map(annotation -> annotation.annotationType().getSimpleName()).collect(Collectors.toList()), getClass().getSimpleName()));
                }
            }
        }

        // 处理方法中的注解信息
        @Override
        protected final void processAnnotationOnMethod(MethodMetadata data, Annotation annotation, Method method) {
            // 遍历所有的方法处理器
            List<GuardedAnnotationProcessor> processors = methodAnnotationProcessors.stream()
                    // 过滤处能处理该注解的所有处理器
                    .filter(processor -> processor.test(annotation))
                    .collect(Collectors.toList());

            // 如果存在能处理该注解的处理器
            if (!processors.isEmpty()) {
                // 执行处理器,解析方法注解
                processors.forEach(processor -> processor.process(annotation, data));
            }
            // 如果没有任何处理器,记录警告信息
            else {
                data.addWarning(String.format("Method %s has an annotation %s that is not used by contract %s", method.getName(), annotation.annotationType().getSimpleName(), getClass().getSimpleName()));
            }
        }

        // 处理参数中的注解
        @Override
        protected final boolean processAnnotationsOnParameter(MethodMetadata data, Annotation[] annotations, int paramIndex) {
            // 遍历所有方法的注解
            List<Annotation> matchingAnnotations = Arrays.stream(annotations)
                    // 过滤存在处理器这些注解
                    .filter(annotation -> parameterAnnotationProcessors.containsKey(annotation.annotationType()))
                    .collect(Collectors.toList());
            // 如果有注解存在处理器
            if (!matchingAnnotations.isEmpty()) {
                // 获取该注解对应的处理器,执行该处理器,执行参数注解解析逻辑
                matchingAnnotations.forEach(annotation -> parameterAnnotationProcessors
                        .getOrDefault(annotation.annotationType(), ParameterAnnotationProcessor.DO_NOTHING)
                        .process(annotation, data, paramIndex));
            }
            // 如果没有任何注解存在对应的处理器
            else {
                // 获取到该下标的参数对象
                Parameter parameter = data.method().getParameters()[paramIndex];
                // 获取参数名
                String parameterName = parameter.isNamePresent() ? parameter.getName() : parameter.getType().getSimpleName();
                // 记录参数的警告信息
                if (annotations.length == 0) {
                    data.addWarning(String.format("Parameter %s has no annotations, it may affect contract %s", parameterName, getClass().getSimpleName()));
                } else {
                    data.addWarning(String.format("Parameter %s has annotations %s that are not used by contract %s", parameterName, Arrays.stream(annotations).map(annotation -> annotation.annotationType().getSimpleName()).collect(Collectors.toList()), getClass().getSimpleName()));
                }
            }
            // 返回不是处理的http相关的注解信息
            return false;
        }

        // 注册类处理器,带有条件
        protected <E extends Annotation> void registerClassAnnotation(Class<E> annotationType, DeclarativeContract.AnnotationProcessor<E> processor) {
            this.registerClassAnnotation(annotation -> annotation.annotationType().equals(annotationType), processor);
        }

        // 注册类处理器,带有条件
        protected <E extends Annotation> void registerClassAnnotation(Predicate<E> predicate, DeclarativeContract.AnnotationProcessor<E> processor) {
            this.classAnnotationProcessors.add(new GuardedAnnotationProcessor(predicate, processor));
        }

        // 注册方法处理器
        protected <E extends Annotation> void registerMethodAnnotation(Class<E> annotationType, DeclarativeContract.AnnotationProcessor<E> processor) {
            this.registerMethodAnnotation(annotation -> annotation.annotationType().equals(annotationType), processor);
        }

        // 注册方法处理器,带有条件
        protected <E extends Annotation> void registerMethodAnnotation(Predicate<E> predicate, DeclarativeContract.AnnotationProcessor<E> processor) {
            this.methodAnnotationProcessors.add(new GuardedAnnotationProcessor(predicate, processor));
        }

        // 注册参数注解处理器
        protected <E extends Annotation> void registerParameterAnnotation(Class<E> annotation, DeclarativeContract.ParameterAnnotationProcessor<E> processor) {
            this.parameterAnnotationProcessors.put((Class) annotation, (DeclarativeContract.ParameterAnnotationProcessor) processor);
        }

        // 标注的注解处理器
        @FunctionalInterface
        public interface AnnotationProcessor<E extends Annotation> {
            void process(E annotation, MethodMetadata metadata);
        }

        // 参数注解处理器
        public interface ParameterAnnotationProcessor<E extends Annotation> {

            DeclarativeContract.ParameterAnnotationProcessor<Annotation> DO_NOTHING = (ann, data, i) -> {
            };

            // 处理指定参数的注解
            void process(E annotation, MethodMetadata metadata, int paramIndex);
        }

        // 带有条件的注解处理器,这是一个装饰者模式
        private class GuardedAnnotationProcessor implements Predicate<Annotation>, DeclarativeContract.AnnotationProcessor<Annotation> {

            // 满足条件,才会执行process方法
            private final Predicate<Annotation> predicate;
            // 注解处理器,这是一个装饰者模式
            private final DeclarativeContract.AnnotationProcessor<Annotation> processor;

            private GuardedAnnotationProcessor(Predicate predicate, DeclarativeContract.AnnotationProcessor processor) {
                this.predicate = predicate;
                this.processor = processor;
            }

            // 处理指定的注解信息
            @Override
            public void process(Annotation annotation, MethodMetadata metadata) {
                processor.process(annotation, metadata);
            }

            // 条件判断
            @Override
            public boolean test(Annotation t) {
                return predicate.test(t);
            }
        }

    }

    // 用于解析类中的SpringMVC类注解,方法注解,参数注解元数据信息
    public class SpringMvcContract extends Contract.BaseContract implements ResourceLoaderAware {

        // 注解参数处理器
        private final Map<Class<? extends Annotation>, AnnotatedParameterProcessor> annotatedArgumentProcessors;
        // 保存正在处理的方法
        private final Map<String, Method> processedMethods = new HashMap<>();
        // 类型转换器
        private final ConversionService conversionService;
        /**
         * 创建类型转换Expander类的工厂类
         * {@link Contract.MethodMetadata#indexToExpander}
         */
        private final ConvertingExpanderFactory convertingExpanderFactory;
        // 资源加载器
        private ResourceLoader resourceLoader = new DefaultResourceLoader();
        // 是否解析解码"/"
        private final boolean decodeSlash;

        public SpringMvcContract() {
            this(Collections.emptyList());
        }

        public SpringMvcContract(List<AnnotatedParameterProcessor> annotatedParameterProcessors) {
            this(annotatedParameterProcessors, new DefaultConversionService());
        }

        public SpringMvcContract(List<AnnotatedParameterProcessor> annotatedParameterProcessors, ConversionService conversionService) {
            this(annotatedParameterProcessors, conversionService, true);
        }

        public SpringMvcContract(List<AnnotatedParameterProcessor> annotatedParameterProcessors, ConversionService conversionService, boolean decodeSlash) {
            // 默认的注解参数处理器
            List<AnnotatedParameterProcessor> processors = this.getDefaultAnnotatedArgumentsProcessors();
            processors.addAll(annotatedParameterProcessors);
            // 将所有处理器转换为支持处理注解->该注解处理器的映射关系
            this.annotatedArgumentProcessors = toAnnotatedArgumentProcessorMap(processors);
            this.conversionService = conversionService;
            this.convertingExpanderFactory = new ConvertingExpanderFactory(conversionService);
            this.decodeSlash = decodeSlash;
        }

        // 处理类注解
        @Override
        protected void processAnnotationOnClass(MethodMetadata data, Class<?> clz) {
            // 获取类中的RequestMapping注解
            RequestMapping classAnnotation = findMergedAnnotation(clz, RequestMapping.class);
            // 校验,如果类中存在该注解,抛出异常,@FeignClient不允许标注
            if (classAnnotation != null) {
                LOG.error("Cannot process class: " + clz.getName() + ". @RequestMapping annotation is not allowed on @FeignClient interfaces.");
                throw new IllegalArgumentException("@RequestMapping annotation not allowed on @FeignClient interfaces");
            }

            // 获取@CollectionFormat注解
            CollectionFormat collectionFormat = findMergedAnnotation(clz, CollectionFormat.class);
            // 如果存在
            if (collectionFormat != null) {
                /**
                 * 设置集合参数的类型转换器,将请求参数按照指定的格式解析为方法参数类型
                 * 例如:
                 * <pre>
                 *      @RequestLine("GET /api/resource?ids={ids}")
                 *      void getResource(@Param(value = "ids", collectionFormat = CollectionFormat.CSV) List<String> ids);
                 * </pre>
                 */
                // 设置到请求模版对象中
                data.template().collectionFormat(collectionFormat.value());
            }
        }

        @Override
        public MethodMetadata parseAndValidateMetadata(Class<?> targetType, Method method) {
            // 保存一下当前方法信息
            processedMethods.put(Feign.configKey(targetType, method), method);
            return super.parseAndValidateMetadata(targetType, method);
        }

        // 处理方法注解
        @Override
        protected void processAnnotationOnMethod(MethodMetadata data, Annotation methodAnnotation, Method method) {
            // 注解是否是CollectionFormat类型
            if (methodAnnotation instanceof CollectionFormat) {
                /**
                 * 设置集合参数的类型转换器,将请求参数按照指定的格式解析为方法参数类型
                 * 例如:
                 * <pre>
                 *      @RequestLine("GET /api/resource?ids={ids}")
                 *      void getResource(@Param(value = "ids", collectionFormat = CollectionFormat.CSV) List<String> ids);
                 * </pre>
                 */
                CollectionFormat collectionFormat = findMergedAnnotation(method, CollectionFormat.class);
                data.template().collectionFormat(collectionFormat.value());
            }
            // 如果方法不是RequestMapping,并且也不是RequestMapping的变种,例如@GetMapping
            if (!(methodAnnotation instanceof RequestMapping) && !methodAnnotation.annotationType().isAnnotationPresent(RequestMapping.class)) {
                return;
            }
            // 获取该注解信息
            RequestMapping methodMapping = findMergedAnnotation(method, RequestMapping.class);
            // 获取请求方式
            RequestMethod[] methods = methodMapping.method();
            // 默认为Get
            if (methods.length == 0) {
                methods = new RequestMethod[]{RequestMethod.GET};
            }
            // 给请求模板设置请求方式
            data.template().method(Request.HttpMethod.valueOf(methods[0].name()));
            // 设置请求路径
            if (methodMapping.value().length > 0) {
                // 获取请求路径
                String pathValue = emptyToNull(methodMapping.value()[0]);
                if (pathValue != null) {
                    // 解析占位符
                    pathValue = resolve(pathValue);
                    if (!pathValue.startsWith("/") && !data.template().path().endsWith("/")) {
                        pathValue = "/" + pathValue;
                    }
                    // 该请求模板设置请求路径
                    data.template().uri(pathValue, true);
                    // 设置是否支持解码"/"
                    if (data.template().decodeSlash() != decodeSlash) {
                        data.template().decodeSlash(decodeSlash);
                    }
                }
            }

            // 解析RequestMapping的信息,并设置到请求模板对象中
            // 解析RequestMapping的produces,服务器提供的媒体类型(服务器响应的媒体类型)
            this.parseProduces(data, method, methodMapping);
            // 解析RequestMapping的consumes,客户端提供的媒体类型(客户端发送的媒体类型)
            this.parseConsumes(data, method, methodMapping);
            // 处理RequestMapping的headers响应头
            this.parseHeaders(data, method, methodMapping);
            // 参数的下标以及将该参数转为String类型的展开器的映射关系
            // 和indexToExpanderClass差不多,但是不在是Class,而是该类的实例对象
            data.indexToExpander(new LinkedHashMap<>());
        }

        // 处理参数注解
        @Override
        protected boolean processAnnotationsOnParameter(MethodMetadata data, Annotation[] annotations, int paramIndex) {
            // 是否是http相关注解
            boolean isHttpAnnotation = false;
            // Jpa的分页支持
            if (Pageable.class.isAssignableFrom(data.method().getParameterTypes()[paramIndex])) {
                // 如果方法参数存在@RequestParam,@SpringQueryMap,@QueryMap,获取参数类型为Map,都返回true
                if (!this.queryMapParamPresent(data)) {
                    // 将Pageable类型的参数标记为QueryMap,因为它包含了page和limit,还有排序多个字段
                    data.queryMapIndex(paramIndex);
                    // 处理的不是http相关注解
                    return false;
                }
            }
            // 创建注解处理的上下文对象
            AnnotatedParameterProcessor.AnnotatedParameterContext context = new SimpleAnnotatedParameterContext(data, paramIndex);
            // 获取方法
            Method method = processedMethods.get(data.configKey());
            // 遍历所有参数注解
            for (Annotation parameterAnnotation : annotations) {
                // 获取到能处理该注解的参数处理器
                AnnotatedParameterProcessor processor = annotatedArgumentProcessors.get(parameterAnnotation.annotationType());
                // 如果存在
                if (processor != null) {
                    Annotation processParameterAnnotation;
                    // 处理@AliasFor
                    processParameterAnnotation = synthesizeWithMethodParameterNameAsFallbackValue(parameterAnnotation, method, paramIndex);
                    /**
                     * 执行该参数处理器,处理该注解信息,例如,处理RequestParam注解
                     * {@link RequestParamParameterProcessor}
                     */
                    // |= 表示任何一个为true,则为true,false与任何值|都是原来的值
                    isHttpAnnotation |= processor.processArgument(context, processParameterAnnotation, method);
                }
            }
            // 如果不是文件表单数据
            if (!this.isMultipartFormData(data) && isHttpAnnotation && data.indexToExpander().get(paramIndex) == null) {
                TypeDescriptor typeDescriptor = createTypeDescriptor(method, paramIndex);
                // 对该参数进行类型转换
                if (conversionService.canConvert(typeDescriptor, STRING_TYPE_DESCRIPTOR)) {
                    // 获取参数展开器,将参数转换为String类型
                    Param.Expander expander = convertingExpanderFactory.getExpander(typeDescriptor);
                    if (expander != null) {
                        // 将该参数转换为String类型
                        data.indexToExpander().put(paramIndex, expander);
                    }
                }
            }
            return isHttpAnnotation;
        }

        // 如果方法参数存在@RequestParam,@SpringQueryMap,@QueryMap,获取参数类型为Map,都返回true
        private boolean queryMapParamPresent(MethodMetadata data) {
            Annotation[][] paramsAnnotations = data.method().getParameterAnnotations();
            for (int i = 0; i < paramsAnnotations.length; i++) {
                Annotation[] paramAnnotations = paramsAnnotations[i];
                Class<?> parameterType = data.method().getParameterTypes()[i];
                if (Arrays.stream(paramAnnotations).anyMatch(annotation -> Map.class.isAssignableFrom(parameterType) && annotation instanceof RequestParam || annotation instanceof SpringQueryMap || annotation instanceof QueryMap)) {
                    return true;
                }
            }
            return false;
        }

        // 将所有处理器转换为支持处理注解->该注解处理器的映射关系
        private Map<Class<? extends Annotation>, AnnotatedParameterProcessor> toAnnotatedArgumentProcessorMap(List<AnnotatedParameterProcessor> processors) {
            Map<Class<? extends Annotation>, AnnotatedParameterProcessor> result = new HashMap<>();
            for (AnnotatedParameterProcessor processor : processors) {
                // 获取该处理器支持处理的注解信息作为Key
                result.put(processor.getAnnotationType(), processor);
            }
            return result;
        }

        // 默认的参数处理器
        private List<AnnotatedParameterProcessor> getDefaultAnnotatedArgumentsProcessors() {
            List<AnnotatedParameterProcessor> annotatedArgumentResolvers = new ArrayList<>();
            // 处理@MatrixVariable
            this.annotatedArgumentResolvers.add(new MatrixVariableParameterProcessor());
            // 处理@PathVariable
            this.annotatedArgumentResolvers.add(new PathVariableParameterProcessor());
            // 处理@RequestParam
            this.annotatedArgumentResolvers.add(new RequestParamParameterProcessor());
            // 处理@RequestHeader
            this.annotatedArgumentResolvers.add(new RequestHeaderParameterProcessor());
            // 处理@QueryMap
            this.annotatedArgumentResolvers.add(new QueryMapParameterProcessor());
            // 处理@RequestPart
            this.annotatedArgumentResolvers.add(new RequestPartParameterProcessor());
            // 处理@CookieValue
            this.annotatedArgumentResolvers.add(new CookieValueParameterProcessor());
            return annotatedArgumentResolvers;
        }


        // 是否是文件表单数据
        private boolean isMultipartFormData(MethodMetadata data) {
            // 获取ContextType
            Collection<String> contentTypes = data.template().headers().get(HttpEncoding.CONTENT_TYPE);
            // 如果为MULTIPART_FORM_DATA,表示为文件表单数据
            if (contentTypes != null && !contentTypes.isEmpty()) {
                String type = contentTypes.iterator().next();
                return Objects.equals(MediaType.valueOf(type), MediaType.MULTIPART_FORM_DATA);
            }

            return false;
        }

        // 创建类型转换Expander类的工厂类
        private static class ConvertingExpanderFactory {

            private final ConversionService conversionService;

            ConvertingExpanderFactory(ConversionService conversionService) {
                this.conversionService = conversionService;
            }

            // 生成扩展器
            Param.Expander getExpander(TypeDescriptor typeDescriptor) {
                return value -> {
                    // 将指定的值转换为Strnig类型
                    Object converted = conversionService.convert(value, typeDescriptor, STRING_TYPE_DESCRIPTOR);
                    return (String) converted;
                };
            }

        }

        // 处理@RequestParam的处理器
        public class RequestParamParameterProcessor implements AnnotatedParameterProcessor {

            private static final Class<RequestParam> ANNOTATION = RequestParam.class;

            // 支持处理类型
            @Override
            public Class<? extends Annotation> getAnnotationType() {
                return ANNOTATION;
            }

            // 处理参数
            @Override
            public boolean processArgument(AnnotatedParameterContext context, Annotation annotation, Method method) {
                // 获取参数索引
                int parameterIndex = context.getParameterIndex();
                // 获取参数类型
                Class<?> parameterType = method.getParameterTypes()[parameterIndex];
                // 获取方法元数据信息
                MethodMetadata data = context.getMethodMetadata();
                // 如果参数为Map
                if (Map.class.isAssignableFrom(parameterType)) {
                    // 校验
                    checkState(data.queryMapIndex() == null, "Query map can only be present once.");
                    // 标记当前下标参数为query的Map参数
                    data.queryMapIndex(parameterIndex);
                    return true;
                }
                // 强转为注解类型
                RequestParam requestParam = ANNOTATION.cast(annotation);
                // 获取参数名
                String name = requestParam.value();
                // 校验不能为空
                checkState(emptyToNull(name) != null, "RequestParam.value() was empty on parameter %s", parameterIndex);
                // 设置参数名
                context.setParameterName(name);
                // 将这些参数添加到请求模版对象的query参数中
                Collection<String> query = context.setTemplateParameter(name, data.template().queries().get(name));
                data.template().query(name, query);
                // 处理的http相关注解
                return true;
            }
        }
    }
}

// 方法的与数据对象
public final class MethodMetadata implements Serializable {
    // 方法的签名
    private String configKey;
    // 方法的返回类型
    private transient Type returnType;
    // 方法参数为URI的索引下标
    private Integer urlIndex;
    // 方法参数需要进行编码为请求体的索引下标
    private Integer bodyIndex;
    // 参数为Map的并且为请求头的索引下标
    private Integer headerMapIndex;
    // 参数为Map的并且为query参数的索引下标
    private Integer queryMapIndex;
    // 该方法是否总是编码请求体
    private boolean alwaysEncodeBody;
    // 请求体类型
    private transient Type bodyType;
    // 请求模板对象
    private final RequestTemplate template = new RequestTemplate();
    // 表单参数
    private final List<String> formParams = new ArrayList<String>();
    // 参数的下标以及名称的映射关系
    private final Map<Integer, Collection<String>> indexToName = new LinkedHashMap<Integer, Collection<String>>();
    // 参数的下标以及将该参数转为String类型的展开器的映射关系
    private final Map<Integer, Class<? extends Expander>> indexToExpanderClass = new LinkedHashMap<Integer, Class<? extends Expander>>();
    // 参数的下标以及将该参数是否需要编码的映射关系
    private final Map<Integer, Boolean> indexToEncoded = new LinkedHashMap<Integer, Boolean>();
    // 参数的下标以及将该参数转为String类型的展开器的映射关系
    // 和indexToExpanderClass差不多,但是不在是Class,而是该类的实例对象
    private transient Map<Integer, Expander> indexToExpander;
    // 需要忽略的参数下标
    private BitSet parameterToIgnore = new BitSet();
    // 当前方法是否需要忽略参数处理
    private boolean ignored;
    // 目标类类型
    private transient Class<?> targetType;
    // 方法对象
    private transient Method method;
    // 验证的警告信息
    private transient final List<String> warnings = new ArrayList<>();

    MethodMetadata() {
        template.methodMetadata(this);
    }
}

// 发送Http请求的客户端
public interface Client {

    /**
     * 发送Http请求
     *
     * @param request 请求对象
     * @param options 请求配置信息
     * @return 响应对象
     */
    Response execute(Request request, Options options) throws IOException;

    // 默认的实现
    class Default implements Client {
        // SSL套接字工厂
        private final SSLSocketFactory sslContextFactory;
        // 主机验证器
        private final HostnameVerifier hostnameVerifier;
        // 禁用请求缓冲
        private final boolean disableRequestBuffering;

        public Default(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier) {
            this(sslContextFactory, hostnameVerifier, true);
        }

        public Default(SSLSocketFactory sslContextFactory, HostnameVerifier hostnameVerifier, boolean disableRequestBuffering) {
            this.sslContextFactory = sslContextFactory;
            this.hostnameVerifier = hostnameVerifier;
            this.disableRequestBuffering = disableRequestBuffering;
        }

        @Override
        public Response execute(Request request, Options options) throws IOException {
            // 转换参数并且发送请求
            HttpURLConnection connection = this.convertAndSend(request, options);
            return this.convertResponse(connection, request);
        }

        public Response convertResponse(HttpURLConnection connection, Request request) throws IOException {
            // 获取响应码
            int status = connection.getResponseCode();
            // 获取响应消息
            String reason = connection.getResponseMessage();
            // 校验状态码
            if (status < 0) {
                throw new IOException(format("Invalid status(%s) executing %s %s", status, connection.getRequestMethod(), connection.getURL()));
            }
            //
            Map<String, Collection<String>> headers = new TreeMap<>(CASE_INSENSITIVE_ORDER);
            // 获取响应头
            for (Map.Entry<String, List<String>> field : connection.getHeaderFields().entrySet()) {
                if (field.getKey() != null) {
                    // 保存响应头
                    headers.put(field.getKey(), field.getValue());
                }
            }
            // 获取内容长度
            Integer length = connection.getContentLength();
            if (length == -1) {
                length = null;
            }
            // 获取响应体
            InputStream stream;
            // 异常请求
            if (status >= 400) {
                // 获取错误的流数据
                stream = connection.getErrorStream();
            }
            // 正常情况
            else {
                // 如果开启了Gzip
                if (this.isGzip(headers.get(CONTENT_ENCODING))) {
                    // 装饰为GZIP流
                    stream = new GZIPInputStream(connection.getInputStream());
                }
                // 如果开启了压缩
                else if (this.isDeflate(headers.get(CONTENT_ENCODING))) {
                    // 装饰为压缩流
                    stream = new InflaterInputStream(connection.getInputStream());
                }
                // 没有开启压缩,获取响应体
                else {
                    stream = connection.getInputStream();
                }
            }
            // 返回响应信息
            return Response.builder().status(status).reason(reason).headers(headers).request(request).body(stream, length).build();
        }

        // 转换参数并且发送请求
        public HttpURLConnection convertAndSend(Request request, Options options) throws IOException {
            // 获取请求的url
            final URL url = new URL(request.url());
            // 获取URL连接
            final HttpURLConnection connection = (HttpURLConnection) url.openConnection();
            // 如果为https
            if (connection instanceof HttpsURLConnection) {
                HttpsURLConnection sslCon = (HttpsURLConnection) connection;
                // 设置SSL套接字工厂
                if (sslContextFactory != null) {
                    sslCon.setSSLSocketFactory(sslContextFactory);
                }
                // 主机验证器
                if (hostnameVerifier != null) {
                    sslCon.setHostnameVerifier(hostnameVerifier);
                }
            }
            // 设置连接时间
            connection.setConnectTimeout(options.connectTimeoutMillis());
            // 设置请求超时时间
            connection.setReadTimeout(options.readTimeoutMillis());
            // 设置是否允许用户交互
            connection.setAllowUserInteraction(false);
            // 设置是否跟随重定向
            connection.setInstanceFollowRedirects(options.isFollowRedirects());
            // 设置请求方式
            connection.setRequestMethod(request.httpMethod().name());
            // 获取指定请求头
            Collection<String> contentEncodingValues = request.headers().get(CONTENT_ENCODING);
            // 是否开启了请求Gzip
            boolean gzipEncodedRequest = this.isGzip(contentEncodingValues);
            // 是否开启了压缩请求
            boolean deflateEncodedRequest = this.isDeflate(contentEncodingValues);
            // 是否存在Accept
            boolean hasAcceptHeader = false;
            // 内容长度
            Integer contentLength = null;
            // 遍历所有的请求头
            for (String field : request.headers().keySet()) {
                if (field.equalsIgnoreCase("Accept")) {
                    hasAcceptHeader = true;
                }
                // 获取请求头的值
                for (String value : request.headers().get(field)) {
                    // 设置contentLength
                    if (field.equals(CONTENT_LENGTH)) {
                        // 如果未开启Gzip或者压缩
                        if (!gzipEncodedRequest && !deflateEncodedRequest) {
                            // 设置内容的长度
                            contentLength = Integer.valueOf(value);
                            connection.addRequestProperty(field, value);
                        }
                    } else {
                        connection.addRequestProperty(field, value);
                    }
                }
            }
            // 添加Accept为*/*
            if (!hasAcceptHeader) {
                connection.addRequestProperty("Accept", "*/*");
            }
            // 是否为空请求体
            boolean hasEmptyBody = false;
            // 获取请求体
            byte[] body = request.body();
            // 如果没有body并且当前请求方式可以携带Body
            if (body == null && request.httpMethod().isWithBody()) {
                // 设置空body并标记
                body = new byte[0];
                hasEmptyBody = true;
            }
            // 如果存在Body
            if (body != null) {
                // 如果禁用请求缓冲,并且存在Body内容
                if (disableRequestBuffering && !hasEmptyBody) {
                    // 设置内容模式
                    if (contentLength != null) {
                        connection.setFixedLengthStreamingMode(contentLength);
                    } else {
                        connection.setChunkedStreamingMode(8196);
                    }
                }
                connection.setDoOutput(true);
                // 获取输出流
                OutputStream out = connection.getOutputStream();
                // 如果开启Gzip
                if (gzipEncodedRequest) {
                    // 装饰为Gzip流
                    out = new GZIPOutputStream(out);
                }
                // 如果开启压缩
                else if (deflateEncodedRequest) {
                    // 装饰为压缩流
                    out = new DeflaterOutputStream(out);
                }
                try {
                    // 将请求体写入流中
                    out.write(body);
                } finally {
                    // 关闭流
                    out.close();
                }
            }
            return connection;
        }

        private boolean isGzip(Collection<String> contentEncodingValues) {
            return contentEncodingValues != null && !contentEncodingValues.isEmpty() && contentEncodingValues.contains(ENCODING_GZIP);
        }

        private boolean isDeflate(Collection<String> contentEncodingValues) {
            return contentEncodingValues != null && !contentEncodingValues.isEmpty() && contentEncodingValues.contains(ENCODING_DEFLATE);
        }
    }

    // Feign阻塞的负载均衡客户端
    public class FeignBlockingLoadBalancerClient implements Client {

        // 实际发送请求的客户端
        private final Client delegate;
        // 负载均衡客户端,负责选择服务实例
        private final LoadBalancerClient loadBalancerClient;
        // 生成LoadBalancerClient的工厂
        private final LoadBalancerClientFactory loadBalancerClientFactory;
        // 对发送的请求对象进行转换的转换类,通过该类可以对Reqeust对象进行加工
        private final List<LoadBalancerFeignRequestTransformer> transformers;

        @Override
        public Response execute(Request request, Request.Options options) throws IOException {
            // 获取URL
            final URI originalUri = URI.create(request.url());
            // 获取主机名
            String serviceId = originalUri.getHost();
            // 获取提示
            String hint = getHint(serviceId);
            // 创建默认的负载均衡请求对象,包括请求数据以及请求数据上下文
            DefaultRequest<RequestDataContext> lbRequest = new DefaultRequest<>(new RequestDataContext(buildRequestData(request), hint));
            // 获取负载均衡的生命周期接口
            Set<LoadBalancerLifecycle> supportedLifecycleProcessors = LoadBalancerLifecycleValidator.getSupportedLifecycleProcessors(loadBalancerClientFactory.getInstances(serviceId, LoadBalancerLifecycle.class), RequestDataContext.class, ResponseData.class, ServiceInstance.class);
            // 执行这些接口的onStart方法
            supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStart(lbRequest));
            // 选择需要请求的实例
            ServiceInstance instance = loadBalancerClient.choose(serviceId, lbRequest);
            // 创建默认的响应对象
            org.springframework.cloud.client.loadbalancer.Response<ServiceInstance> lbResponse = new DefaultResponse(instance);
            // 如果没有获取到服务实例
            if (instance == null) {
                String message = "Load balancer does not contain an instance for the service " + serviceId;
                if (LOG.isWarnEnabled()) {
                    LOG.warn(message);
                }
                // 执行生命周期的完成方法
                supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<ResponseData, ServiceInstance, RequestDataContext>(CompletionContext.Status.DISCARD, lbRequest, lbResponse)));
                // 返回响应对象,响应码为503(服务不可用)
                return Response.builder().request(request).status(HttpStatus.SERVICE_UNAVAILABLE.value()).body(message, StandardCharsets.UTF_8).build();
            }
            // 解析最终请求的URL
            String reconstructedUrl = loadBalancerClient.reconstructURI(instance, originalUri).toString();
            // 构建最终的请求对象
            Request newRequest = this.buildRequest(request, reconstructedUrl, instance);
            // 执行生命周期方法,开始发送请求
            supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onStartRequest(lbRequest, lbResponse));
            try {
                // 发送http请求
                Response response = feignClient.execute(feignRequest, options);
                // 如果是负载均衡,执行onComplete完成方法的生命周期
                if (loadBalanced) {
                    supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.SUCCESS, lbRequest, lbResponse, buildResponseData(response))));
                }
                // 返回响应结果
                return response;
            } catch (Exception exception) {
                // 异常结束,也执行完成的生命周期方法
                if (loadBalanced) {
                    supportedLifecycleProcessors.forEach(lifecycle -> lifecycle.onComplete(new CompletionContext<>(CompletionContext.Status.FAILED, exception, lbRequest, lbResponse)));
                }
                // 抛出异常
                throw exception;
            }
        }

        // 创建基础的请求对象
        protected Request buildRequest(Request request, String reconstructedUrl) {
            return Request.create(request.httpMethod(), reconstructedUrl, request.headers(), request.body(), request.charset(), request.requestTemplate());
        }

        // 构建请求对象并加工
        protected Request buildRequest(Request request, String reconstructedUrl, ServiceInstance instance) {
            // 创建基础的请求对象
            Request newRequest = this.buildRequest(request, reconstructedUrl);
            // 对发送的请求对象进行转换的转换类,通过该类可以对Reqeust对象进行加工
            if (transformers != null) {
                // 遍历所有的请求对象转换器,对请求进行加工
                for (LoadBalancerFeignRequestTransformer transformer : transformers) {
                    // 返回新的请求对象
                    newRequest = transformer.transformRequest(newRequest, instance);
                }
            }
            return newRequest;
        }
    }

}

// 请求模板对象
public final class RequestTemplate implements Serializable {
    // 参数正则
    // 用于匹配查询字符串中的 ?
    private static final Pattern QUERY_STRING_PATTERN = Pattern.compile("(?<!\\{)\\?");
    // 请求参数
    private final Map<String, QueryTemplate> queries = new LinkedHashMap<>();
    // 请求头
    private final Map<String, HeaderTemplate> headers = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
    // 请求的目标 URL
    private String target;
    // 请求的片段(Fragment)部分
    private String fragment;
    // 表示请求模板是否已解析
    private boolean resolved = false;
    // 请求的 URI 模板
    private UriTemplate uriTemplate;
    // 请求的消息体模板
    private BodyTemplate bodyTemplate;
    // 请求方式
    private HttpMethod method;
    // 字符集
    private transient Charset charset = Util.UTF_8;
    // 请求体数据
    private Request.Body body = Request.Body.empty();
    // 是否解码"/"
    private boolean decodeSlash = true;
    // 按照什么格式将集合类型的参数转换为请求体
    private CollectionFormat collectionFormat = CollectionFormat.EXPLODED;
    // 方法的元数据对象
    private MethodMetadata methodMetadata;
    // FeignClinet接口信息
    private Target<?> feignTarget;

    // 创建RequestTemplate的工厂类
    interface Factory {
        RequestTemplate create(Object[] argv);
    }

    // 根据所有请求参数变量解析
    public RequestTemplate resolve(Map<String, ?> variables) {
        // 最终请求url
        StringBuilder uri = new StringBuilder();
        // 创建新的请求模板对象
        RequestTemplate resolved = RequestTemplate.from(this);
        // 如果不存在请求的url模板
        if (this.uriTemplate == null) {
            // 创建一个uri的模板对象,该对象最终会得到一个可用的url(可能需要进行解码,编码等操作)
            this.uriTemplate = UriTemplate.create("", !this.decodeSlash, this.charset);
        }
        // 扩展url(解析url表达式)
        String expanded = this.uriTemplate.expand(variables);
        // 保存解析的url
        if (expanded != null) {
            uri.append(expanded);
        }
        // 如果存在query参数,进行?,&拼接
        if (!this.queries.isEmpty()) {
            // 初始化query参数集合
            resolved.queries(Collections.emptyMap());
            StringBuilder query = new StringBuilder();
            // 获取所有的请求参数
            Iterator<QueryTemplate> queryTemplates = this.queries.values().iterator();
            // 遍历所有的请求参数
            while (queryTemplates.hasNext()) {
                QueryTemplate queryTemplate = queryTemplates.next();
                // 扩展请求参数(解析参数表达式)
                String queryExpanded = queryTemplate.expand(variables);
                if (Util.isNotBlank(queryExpanded)) {
                    query.append(queryExpanded);
                    if (queryTemplates.hasNext()) {
                        query.append("&");
                    }
                }
            }
            // 拼接query参数
            String queryString = query.toString();
            if (!queryString.isEmpty()) {
                Matcher queryMatcher = QUERY_STRING_PATTERN.matcher(uri);
                if (queryMatcher.find()) {
                    uri.append("&");
                } else {
                    uri.append("?");
                }
                uri.append(queryString);
            }
        }

        // 设置解析好的uri
        resolved.uri(uri.toString());

        // 如果存在请求头
        if (!this.headers.isEmpty()) {
            // 初始化请求头集合
            resolved.headers(Collections.emptyMap());
            // 遍历所有请求头
            for (HeaderTemplate headerTemplate : this.headers.values()) {
                // 扩展请求头(解析请求头表达式)
                String header = headerTemplate.expand(variables);
                if (!header.isEmpty()) {
                    // 添加请求头
                    resolved.appendHeader(headerTemplate.getName(), Collections.singletonList(header), true);
                }
            }
        }

        // 如果存在body
        if (this.bodyTemplate != null) {
            // 扩展body(解析body表达式)
            resolved.body(this.bodyTemplate.expand(variables));
        }
        // 标记该请求模板已被解析
        resolved.resolved = true;
        return resolved;
    }

}

// 负载均衡Feign的请求对象的转换器,在Feign发送请求的时候,在发送之前会执行该操作
@Order(LoadBalancerFeignRequestTransformer.DEFAULT_ORDER)
public interface LoadBalancerFeignRequestTransformer {
    int DEFAULT_ORDER = 0;

    /**
     * 将给定的请求对象以及选择的服务实例对象进过加工,转换为新的请求对象
     *
     * @param request  原始请求对象
     * @param instance 服务实例
     * @return 新的请求对象
     */
    Request transformRequest(Request request, ServiceInstance instance);


    public class XForwardedHeadersTransformer implements LoadBalancerFeignRequestTransformer {

        private final ReactiveLoadBalancer.Factory<ServiceInstance> factory;

        public XForwardedHeadersTransformer(ReactiveLoadBalancer.Factory<ServiceInstance> factory) {
            this.factory = factory;
        }

        // 加工请求
        @Override
        public Request transformRequest(Request request, ServiceInstance instance) {
            if (instance == null) {
                return request;
            }
            LoadBalancerProperties.XForwarded xForwarded = factory.getProperties(instance.getServiceId()).getXForwarded();
            if (xForwarded.isEnabled()) {
                Map<String, Collection<String>> headers = new HashMap<>(request.headers());
                URI uri = URI.create(request.url());
                String xForwardedHost = uri.getHost();
                String xForwardedProto = uri.getScheme();
                headers.put("X-Forwarded-Host", Collections.singleton(xForwardedHost));
                headers.put("X-Forwarded-Proto", Collections.singleton(xForwardedProto));
                request = Request.create(request.httpMethod(), request.url(), headers, request.body(), request.charset(), request.requestTemplate());
            }
            return request;
        }

    }

}

// 基于反射的Feign对象,Feign对象是整个Feign的核心类
public class ReflectiveFeign<C> extends Feign {

    // 目标方法执行器的处理类解析器
    private final ParseHandlersByName<C> targetToHandlersByName;
    // 创建动态代理对象InvocationHandler的工厂类
    private final InvocationHandlerFactory factory;
    // 创建异步上下文的提供者,默认情况不提供异步上下文,只有在异步执行的时候才会有
    private final AsyncContextSupplier<C> defaultContextSupplier;

    public ReflectiveFeign(Contract contract, MethodHandler.Factory<C> methodHandlerFactory, InvocationHandlerFactory invocationHandlerFactory, AsyncContextSupplier<C> defaultContextSupplier) {
        this.targetToHandlersByName = new ParseHandlersByName<C>(contract, methodHandlerFactory);
        this.factory = invocationHandlerFactory;
        this.defaultContextSupplier = defaultContextSupplier;
    }

    // 创建代理对象
    public <T> T newInstance(Target<T> target) {
        // 创建新的上下文对象,并返回代理对象
        return newInstance(target, defaultContextSupplier.newContext());
    }

    // 创建FeignClient的代理对象
    public <T> T newInstance(Target<T> target, C requestContext) {
        // 验证目标对象中的方法是否符合规范,比如返回值,类必须是接口
        TargetSpecificationVerifier.verify(target);
        // 将目标接口FeignClient的所有方法转换为可执行的方法处理器
        Map<Method, MethodHandler> methodToHandler = targetToHandlersByName.apply(target, requestContext);
        // 创建InvocationHandler
        InvocationHandler handler = factory.create(target, methodToHandler);
        // 创建代理对象
        T proxy = (T) Proxy.newProxyInstance(target.type().getClassLoader(), new Class<?>[]{target.type()}, handler);
        // 使用代理对象绑定接口的默认方法
        for (MethodHandler methodHandler : methodToHandler.values()) {
            if (methodHandler instanceof DefaultMethodHandler) {
                ((DefaultMethodHandler) methodHandler).bindTo(proxy);
            }
        }
        return proxy;
    }

    // Feign的代理对象执行器
    public class FeignInvocationHandler implements InvocationHandler {
        // 目标接口
        private final Target target;
        // 目标接口的所有方法->方法执行器的映射关系
        private final Map<Method, MethodHandler> dispatch;

        FeignInvocationHandler(Target target, Map<Method, MethodHandler> dispatch) {
            this.target = checkNotNull(target, "target");
            this.dispatch = checkNotNull(dispatch, "dispatch for %s", target);
        }

        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            // 获取到该方法对应的执行器进行执行
            return dispatch.get(method).invoke(args);
        }
    }

    // 目标方法执行器的处理类解析器
    private static final class ParseHandlersByName<C> {

        // 用于解析类中的所有方法的元数据信息,包括类注解,方法注解,参数注解
        private final Contract contract;
        // 创建方法处理器的工厂
        private final MethodHandler.Factory<C> factory;

        public ParseHandlersByName(Contract contract, MethodHandler.Factory<C> factory) {
            this.contract = contract;
            this.factory = factory;
        }

        // 将目标接口FeignClient的所有方法转换为可执行的方法处理器
        public Map<Method, MethodHandler> apply(Target target, C requestContext) {
            final Map<Method, MethodHandler> result = new LinkedHashMap<>();
            // 解析目标类的方法元数据信息
            final List<MethodMetadata> metadataList = contract.parseAndValidateMetadata(target.type());
            // 遍历所有的方法元数据
            for (MethodMetadata md : metadataList) {
                // 排除Object的方法
                final Method method = md.method();
                if (method.getDeclaringClass() == Object.class) {
                    continue;
                }
                // 创建方法处理器
                final MethodHandler handler = this.createMethodHandler(target, md, requestContext);
                // 保存方法->方法执行器的映射关系
                result.put(method, handler);
            }
            // 处理接口的默认方法
            for (Method method : target.type().getMethods()) {
                if (Util.isDefault(method)) {
                    // 默认方法是有DefaultMethodHandler执行
                    final MethodHandler handler = new DefaultMethodHandler(method);
                    // 保存方法->方法执行器的映射关系
                    result.put(method, handler);
                }
            }
            return result;
        }

        // 创建方法执行器
        private MethodHandler createMethodHandler(Target<?> target, MethodMetadata md, C requestContext) {
            // 如果方法设置了被忽略,那么执行该方法将会抛出一个异常
            if (md.isIgnored()) {
                return args -> {
                    throw new IllegalStateException(md.configKey() + " is not a method handled by feign");
                };
            }
            // 创建方法执行器
            return factory.create(target, md, requestContext);
        }
    }

    // 目标接口验证器
    private static class TargetSpecificationVerifier {
        // 验证
        public static <T> void verify(Target<T> target) {
            Class<T> type = target.type();
            // 必须是接口
            if (!type.isInterface()) {
                throw new IllegalArgumentException("Type must be an interface: " + type);
            }

            // 遍历所有的方法
            for (final Method m : type.getMethods()) {
                final Class<?> retType = m.getReturnType();
                // 验证返回值为CompletableFuture的情况,如果不是,则不验证
                if (!CompletableFuture.class.isAssignableFrom(retType)) {
                    continue;
                }
                // 只能使用CompletableFuture,CompletableFuture的子类都不行
                if (retType != CompletableFuture.class) {
                    throw new IllegalArgumentException("Method return type is not CompleteableFuture: " + getFullMethodName(type, retType, m));
                }
                // 获取方法CompletableFuture泛型
                final Type genRetType = m.getGenericReturnType();
                // 如果不存在泛型,抛出异常
                // 也就是必须有泛型
                if (!(genRetType instanceof ParameterizedType)) {
                    throw new IllegalArgumentException("Method return type is not parameterized: " + getFullMethodName(type, genRetType, m));

                }
                // 并且泛型是具体的类,不能是通配符
                if (((ParameterizedType) genRetType).getActualTypeArguments()[0] instanceof WildcardType) {
                    throw new IllegalArgumentException("Wildcards are not supported for return-type parameters: " + getFullMethodName(type, genRetType, m));
                }
            }
        }

        // 获取方法名全称
        private static String getFullMethodName(Class<?> type, Type retType, Method m) {
            return retType.getTypeName() + " " + type.toGenericString() + "." + m.getName();
        }
    }
}

// 方法处理器,具体执行方法的类
public interface MethodHandler {
    // 执行目标方法
    Object invoke(Object[] argv) throws Throwable;

    // 创建方法处理器MethodHandler的工厂类
    public interface Factory<C> {
        MethodHandler create(Target<?> target, MethodMetadata md, C requestContext);
    }


    // 同步执行的方法执行器
    public class SynchronousMethodHandler implements MethodHandler {
        // 方法元数据
        private final MethodMetadata metadata;
        // 目标类信息
        private final Target<?> target;
        // 发送Http请求的客户端
        private final Client client;
        // 重试器
        private final Retryer retryer;
        // 请求拦截器
        private final List<RequestInterceptor> requestInterceptors;
        // 日志对象
        private final Logger logger;
        // 日志级别对象
        private final Logger.Level logLevel;
        // 请求模板工厂
        private final RequestTemplate.Factory buildTemplateFromArgs;
        // 请求参数配置
        private final Options options;
        // 异常的传播机制
        private final ExceptionPropagationPolicy propagationPolicy;
        // 响应处理器
        private final ResponseHandler responseHandler;

        // 执行目标方法
        @Override
        public Object invoke(Object[] argv) throws Throwable {
            // 使用工厂创建请求模板对象
            RequestTemplate template = buildTemplateFromArgs.create(argv);
            // 重找请求配置信息
            Options options = this.findOptions(argv);
            // 克隆请求重试的信息
            Retryer retryer = this.retryer.clone();
            // 不断重试
            while (true) {
                try {
                    // 执行请求
                    return this.executeAndDecode(template, options);
                }
                // 只有抛出RetryableException才会重试,其他异常不会重试,而是抛出
                catch (RetryableException e) {
                    try {
                        // 重试
                        retryer.continueOrPropagate(e);
                    } catch (RetryableException th) {
                        Throwable cause = th.getCause();
                        // 如果传播策略为无需包装,则返账原有异常
                        if (propagationPolicy == UNWRAP && cause != null) {
                            throw cause;
                        }
                        // 否则返回包装的RetryableException
                        else {
                            throw th;
                        }
                    }
                    // 打印日志
                    if (logLevel != Logger.Level.NONE) {
                        logger.logRetry(metadata.configKey(), logLevel);
                    }
                    continue;
                }
            }
        }

        // 执行并对响应体解码
        public Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
            // 执行所有的请求拦截器并返回请求对象
            Request request = this.targetRequest(template);
            // 打印请求日志
            if (logLevel != Logger.Level.NONE) {
                logger.logRequest(metadata.configKey(), logLevel, request);
            }
            // 响应对象
            Response response;
            // 请求开始时间
            long start = System.nanoTime();
            try {
                // 发送http请求
                response = client.execute(request, options);
                // 封装为响应对象,设置一些参数
                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);
            // 使用响应处理器处理响应
            return responseHandler.handleResponse(metadata.configKey(), response, metadata.returnType(), elapsedTime);

        }

        // 执行所有的请求拦截器
        public Request targetRequest(RequestTemplate template) {
            // 执行拦截器
            for (RequestInterceptor interceptor : requestInterceptors) {
                interceptor.apply(template);
            }
            // 给请求模板设置目标url,并返回请求目标的request对象
            return target.apply(template);
        }

        // 查找发送请求的配置对象
        public Options findOptions(Object[] argv) {
            // 如果不存在任何参数,返回当前对象的配置信息
            if (argv == null || argv.length == 0) {
                return this.options;
            }
            // 如果存在给定参数,从参数中找到Options类型的参数作为配置对象,如果参数中也不存在,则返回当前对象的配置信息
            return Stream.of(argv).filter(Options.class::isInstance).map(Options.class::cast).findFirst().orElse(this.options);

        }

        // 生成MethodHandler的工厂
        public static class Factory implements MethodHandler.Factory<Object> {

            private final Client client;
            private final Retryer retryer;
            private final List<RequestInterceptor> requestInterceptors;
            private final ResponseHandler responseHandler;
            private final Logger logger;
            private final Logger.Level logLevel;
            private final ExceptionPropagationPolicy propagationPolicy;
            // 请求模板RequestTemplate的工厂解析器,用于解析请求模板对象的核心类
            // 通过该解析器可以解析到RequestTemplateFactory,然通过RequestTemplateFactory创建RequestTemplate对象
            private final RequestTemplateFactoryResolver requestTemplateFactoryResolver;
            private final Options options;

            // 创建对象
            public MethodHandler create(Target<?> target, MethodMetadata md, Object requestContext) {
                // 使用请求模板工厂解析目标类对应的方法元数据,得到请求模板工厂类
                // 该工厂会根据执行参数解析成请求模板RequestTemplate对象
                final RequestTemplate.Factory buildTemplateFromArgs = requestTemplateFactoryResolver.resolve(target, md);
                // 创建同步的方法执行器
                return new SynchronousMethodHandler(target, client, retryer, requestInterceptors, logger, logLevel, md, buildTemplateFromArgs, options, responseHandler, propagationPolicy);
            }
        }
    }

}

// 创建动态代理对象InvocationHandler的工厂类
public interface InvocationHandlerFactory {

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


    // 默认的实现
    static final class Default implements InvocationHandlerFactory {

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

// 请求模板RequestTemplate的工厂解析器,用于解析请求模板对象的核心类
// 通过该解析器可以解析到RequestTemplateFactory,然通过RequestTemplateFactory创建RequestTemplate对象
public class RequestTemplateFactoryResolver {
    // 请求体编码器
    private final Encoder encoder;
    // 将请求参数转换为map的编码请
    private final QueryMapEncoder queryMapEncoder;

    public RequestTemplateFactoryResolver(Encoder encoder, QueryMapEncoder queryMapEncoder) {
        this.encoder = checkNotNull(encoder, "encoder");
        this.queryMapEncoder = checkNotNull(queryMapEncoder, "queryMapEncoder");
    }

    // 解析目标方法元数据,根据给请求模板设置的Body来指定不同的模板工厂
    public RequestTemplate.Factory resolve(Target<?> target, MethodMetadata md) {
        // 如果存在表单参数,并且没有请求body参数
        if (!md.formParams().isEmpty() && md.template().bodyTemplate() == null) {
            return new BuildFormEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
        }
        // 如果存在body参数,或者该方法设置了总是编码body
        if (md.bodyIndex() != null || md.alwaysEncodeBody()) {
            return new BuildEncodedTemplateFromArgs(md, encoder, queryMapEncoder, target);
        }
        return new BuildTemplateByResolvingArgs(md, queryMapEncoder, target);
    }

    // 通过解析参数构建模板对象
    private static class BuildTemplateByResolvingArgs implements RequestTemplate.Factory {

        // 将方法参数转换为map的编码器
        private final QueryMapEncoder queryMapEncoder;
        // 方法元数据对象
        protected final MethodMetadata metadata;
        // 目标接口
        protected final Target<?> target;
        // 方法参数下标对应的转换为String参数类型的扩展器
        private final Map<Integer, Param.Expander> indexToExpander = new LinkedHashMap<Integer, Param.Expander>();

        private BuildTemplateByResolvingArgs(MethodMetadata metadata, QueryMapEncoder queryMapEncoder, Target target) {
            this.metadata = metadata;
            this.target = target;
            this.queryMapEncoder = queryMapEncoder;
            if (metadata.indexToExpander() != null) {
                indexToExpander.putAll(metadata.indexToExpander());
                return;
            }
            if (metadata.indexToExpanderClass().isEmpty()) {
                return;
            }
            // 实例化Param.Expander的class类
            for (Map.Entry<Integer, Class<? extends Param.Expander>> indexToExpanderClass : metadata.indexToExpanderClass().entrySet()) {
                indexToExpander.put(indexToExpanderClass.getKey(), indexToExpanderClass.getValue().newInstance());
            }
        }

        @Override
        public RequestTemplate create(Object[] argv) {
            // 创建请求模板对象
            RequestTemplate mutable = RequestTemplate.from(metadata.template());
            // 设置目标对象
            mutable.feignTarget(target);
            // 设置
            if (metadata.urlIndex() != null) {
                // 获取参数为URI的类型的下标
                int urlIndex = metadata.urlIndex();
                // 校验参数
                checkArgument(argv[urlIndex] != null, "URI parameter %s was null", urlIndex);
                // 设置访问的目标URL
                mutable.target(String.valueOf(argv[urlIndex]));
            }
            // 所有的请求参数变量
            Map<String, Object> varBuilder = new LinkedHashMap<String, Object>();
            // 遍历所有的参数下标->参数名称的集合
            for (Map.Entry<Integer, Collection<String>> entry : metadata.indexToName().entrySet()) {
                // 参数下标
                int i = entry.getKey();
                // 参数值
                Object value = argv[i];
                // 如果值为空,则跳过
                if (value != null) {
                    if (indexToExpander.containsKey(i)) {
                        // 方法参数下标对应的转换为String参数类型的扩展器
                        // 如果value为集合,则返回List<String>,否则返回String
                        value = expandElements(indexToExpander.get(i), value);
                    }
                    // 遍历所有的参数名称
                    for (String name : entry.getValue()) {
                        // 保存参数名->参数值的映射
                        varBuilder.put(name, value);
                    }
                }
            }
            // 解析这些请求相关配置
            RequestTemplate template = this.resolve(argv, mutable, varBuilder);
            // 参数为Map的并且为query参数的索引下标(例如,标注了参数注解@QueryMap)
            if (metadata.queryMapIndex() != null) {
                // 获取参数值
                Object value = argv[metadata.queryMapIndex()];
                // 将参数值转换为Map,如果是map则不需要转换,如果不是map,则需要使用queryMapEncoder进行转换
                Map<String, Object> queryMap = toQueryMap(value);
                // 添加请求参数到模板对象中
                template = addQueryMapQueryParameters(queryMap, template);
            }
            // 参数为Map的并且为header的索引下标(例如,标注了参数注解@HeaderMap)
            if (metadata.headerMapIndex() != null) {
                // 获取参数值
                Object value = argv[metadata.headerMapIndex()];
                // 将参数值转换为Map,如果是map则不需要转换,如果不是map,则需要使用queryMapEncoder进行转换
                Map<String, Object> headerMap = toQueryMap(value);
                // 添加请求头到模板对象中
                template = addHeaderMapHeaders(headerMap, template);
            }
            return template;
        }

        // 将参数值转换为Map,如果是map则不需要转换,如果不是map,则需要使用queryMapEncoder进行转换
        private Map<String, Object> toQueryMap(Object value) {
            if (value instanceof Map) {
                return (Map<String, Object>) value;
            }
            return queryMapEncoder.encode(value);
        }

        // 执行参数的扩展方法,将参数转换为String类型,最终发送请求参数
        private Object expandElements(Param.Expander expander, Object value) {
            // 将每一个参数进行转换
            if (value instanceof Iterable) {
                List<String> values = new ArrayList<String>();
                for (Object element : value) {
                    if (element != null) {
                        values.add(expander.expand(element));
                    }
                }
                return values;
            }
            // 直接转换
            return expander.expand(value);
        }

        // 解析请求模板
        protected RequestTemplate resolve(Object[] argv, RequestTemplate mutable, Map<String, Object> variables) {
            return mutable.resolve(variables);
        }
    }

    // 通过参数构建表单编码器模板对象
    private static class BuildFormEncodedTemplateFromArgs extends BuildTemplateByResolvingArgs {
        // 编码器
        private final Encoder encoder;

        private BuildFormEncodedTemplateFromArgs(MethodMetadata metadata, Encoder encoder, QueryMapEncoder queryMapEncoder, Target target) {
            super(metadata, queryMapEncoder, target);
            this.encoder = encoder;
        }

        @Override
        protected RequestTemplate resolve(Object[] argv, RequestTemplate mutable, Map<String, Object> variables) {
            Map<String, Object> formVariables = new LinkedHashMap<String, Object>();
            // 保存表单参数
            for (Map.Entry<String, Object> entry : variables.entrySet()) {
                if (metadata.formParams().contains(entry.getKey())) {
                    formVariables.put(entry.getKey(), entry.getValue());
                }
            }
            // 使用编码器对表单参数进行编码,并且值到body中,因为表单可能含有文件
            encoder.encode(formVariables, Encoder.MAP_STRING_WILDCARD, mutable);
            // 解析请求模板对象
            return super.resolve(argv, mutable, variables);
        }
    }

    // 通过参数构建普通编码器模板对象
    private static class BuildEncodedTemplateFromArgs extends BuildTemplateByResolvingArgs {
        // 编码器
        private final Encoder encoder;

        private BuildEncodedTemplateFromArgs(MethodMetadata metadata, Encoder encoder, QueryMapEncoder queryMapEncoder, Target target) {
            super(metadata, queryMapEncoder, target);
            this.encoder = encoder;
        }

        @Override
        protected RequestTemplate resolve(Object[] argv, RequestTemplate mutable, Map<String, Object> variables) {
            // 是否标注了总是需要编码body
            boolean alwaysEncodeBody = mutable.methodMetadata().alwaysEncodeBody();

            Object body = null;
            // 如果未设置
            if (!alwaysEncodeBody) {
                // 校验body参数
                body = argv[metadata.bodyIndex()];
                checkArgument(body != null, "Body parameter %s was null", metadata.bodyIndex());
            }
            // 如果设置了
            if (alwaysEncodeBody) {
                // 将参数进行编码,并设置到body中
                body = argv == null ? new Object[0] : argv;
                encoder.encode(body, Object[].class, mutable);
            } else {
                encoder.encode(body, metadata.bodyType(), mutable);
            }
            // 解析请求模板对象
            return super.resolve(argv, mutable, variables);
        }
    }
}

// 响应结果处理器
public class ResponseHandler {
    // 最大响应缓冲区大小
    private static final long MAX_RESPONSE_BUFFER_SIZE = 8192L;
    // 日志级别
    private final Level logLevel;
    // 日志对象
    private final Logger logger;
    // 解码器,将响应体解码成返回值
    private final Decoder decoder;
    // 错误解码器,就是处理错误的响应结果的处理器(例如处理404,400)
    // 也就是如何返回指定的异常通知下一步需要做什么,例如: 抛出RetryableException表示继续发起重试
    private final ErrorDecoder errorDecoder;
    // 是否应该解码404而不是抛出feigexception,默认为false
    // 如果为true,404也会返回对应的结果
    private final boolean dismiss404;
    // 解码之后是否关闭资源(默认为true)
    private final boolean closeAfterDecode;
    // 响应拦截器,负责解码操作
    // 每一个FeignClient只需要存在一个响应拦截器,如果需要多个拦截器配合工作,我们可以自定义ResponseInterceptor,管理所有的ResponseInterceptor进行工作
    private final ResponseInterceptor responseInterceptor;

    // 处理响应结果
    public Object handleResponse(String configKey, Response response, Type returnType, long elapsedTime) throws Exception {
        try {
            // 打印响应的相关日志
            response = logAndRebufferResponseIfNeeded(configKey, response, elapsedTime);
            // 如果方法返回值就是Response
            if (returnType == Response.class) {
                // 如果响应体的内容大小大于最大的缓冲区,则断开响应体,关闭流(响应体可能就是流)
                return disconnectResponseBodyIfNeeded(response);
            }
            // 是否需要解码响应体,根据请求状态决定
            final boolean shouldDecodeResponseBody = (response.status() >= 200 && response.status() < 300) || (response.status() == 404 && dismiss404 && !isVoidType(returnType));
            // 如果不需要,抛出异常
            if (!shouldDecodeResponseBody) {
                // 使用错误编码器进行编码
                throw errorDecoder.decode(methodKey, response);
            }
            // 正确结果,对结果进行解码
            return this.decode(response, returnType);
        } catch (final IOException e) {
            // 根据日志级别打印日志信息
            if (logLevel != Level.NONE) {
                logger.logIOException(configKey, logLevel, e, elapsedTime);
            }
            throw errorReading(response.request(), response, e);
        }
    }

    // 打印响应的相关日志
    private Response logAndRebufferResponseIfNeeded(String configKey, Response response, long elapsedTime) throws IOException {
        if (logLevel == Level.NONE) {
            return response;
        }
        return logger.logAndRebufferResponse(configKey, logLevel, response, elapsedTime);
    }

    // 如果需要,断开响应体(响应体可能就是流)
    private static Response disconnectResponseBodyIfNeeded(Response response) throws IOException {
        // 是否需要断开响应体,存在body,并且body已经超过最大的缓冲大小了
        final boolean shouldDisconnectResponseBody =
                response.body() != null
                        && response.body().length() != null
                        && response.body().length() <= MAX_RESPONSE_BUFFER_SIZE;
        // 如果不需要,直接返回
        if (!shouldDisconnectResponseBody) {
            return response;
        }
        // 需要断开响应体
        try {
            // 返回新的Response对象
            final byte[] bodyData = Util.toByteArray(response.body().asInputStream());
            return response.toBuilder().body(bodyData).build();
        } finally {
            // 关闭响应体(响应体可能就是流)
            response.body().close();
        }
    }

    // 解码响应体
    private Object decode(Response response, Type type) throws IOException {
        // 如果是void,返回null
        if (isVoidType(type)) {
            // 关闭响应体
            response.body().close();
            return null;
        }
        try {
            // 执行所有响应拦截器,得到最终的的结果
            final Object result = responseInterceptor.aroundDecode(new InvocationContext(decoder, type, response));
            // 如果解码后需要关闭资源
            if (closeAfterDecode) {
                // 关闭响应体
                response.body().close();
            }
            // 返回编码后的结果
            return result;
        } catch (Exception e) {
            response.body().close();
            throw e;
        }
    }
}

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值