0%

Feign的执行流程

Feign的执行流程

  • 首先通过@EnableFeignClients注解开启Feign功能,程序启动时开启对@FeignClient注解的扫描

    1
    2
    3
    4
    5
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.TYPE)
    @Documented
    @Import(FeignClientsRegistrar.class)
    public @interface EnableFeignClients
  • 当接口的方法调用时,通过动态代理SynchronousMethodHandler生成具体的RequestTemplate

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public Object invoke(Object[] argv) throws Throwable {
    RequestTemplate template = buildTemplateFromArgs.create(argv);
    Options options = findOptions(argv);
    Retryer retryer = this.retryer.clone();
    while (true) {
    try {
    return executeAndDecode(template, options);
    } catch (RetryableException e) {
    try {
    retryer.continueOrPropagate(e);
    } catch (RetryableException th) {
    Throwable cause = th.getCause();
    if (propagationPolicy == UNWRAP && cause != null) {
    throw cause;
    } else {
    throw th;
    }
    }
    if (logLevel != Logger.Level.NONE) {
    logger.logRetry(metadata.configKey(), logLevel);
    }
    continue;
    }
    }
    }
1
RequestTemplate template = buildTemplateFromArgs.create(argv);

在构建RequestTemplate的时候会进行参数解析,如果参数是@RequestBody的会调用Encoder的encode方法进行编码(BuildEncodedTemplateFromArgs)

1
encoder.encode(body, metadata.bodyType(), mutable);
  • 再根据RequestTemplate生成HTTP的Request对象

  • Request对象交给Client处理,可配置HttpURLConnection、HttpClient、OkHttp等

    1
    2
    3
    // 该方法首先会调用RequestInterceptor的apply方法处理请求,之后才会进行请求发送
    // 执行完之后调用Decoder的decode方法来进行解码
    return executeAndDecode(template, options);
  • Client被封装到LoadBalanceClient类进行负载均衡

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
Object executeAndDecode(RequestTemplate template, Options options) throws Throwable {
// 调用RequestInterceptor的apply方法处理请求
Request request = targetRequest(template);

if (logLevel != Logger.Level.NONE) {
logger.logRequest(metadata.configKey(), logLevel, request);
}

Response response;
long start = System.nanoTime();
try {
// 请求发送
response = client.execute(request, options);
} 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);

boolean shouldClose = true;
try {
if (logLevel != Logger.Level.NONE) {
response =
logger.logAndRebufferResponse(metadata.configKey(), logLevel, response, elapsedTime);
}
if (Response.class == metadata.returnType()) {
if (response.body() == null) {
return response;
}
if (response.body().length() == null ||
response.body().length() > MAX_RESPONSE_BUFFER_SIZE) {
shouldClose = false;
return response;
}
// Ensure the response body is disconnected
byte[] bodyData = Util.toByteArray(response.body().asInputStream());
return response.toBuilder().body(bodyData).build();
}
if (response.status() >= 200 && response.status() < 300) {
if (void.class == metadata.returnType()) {
return null;
} else {
//调用Decoder的decode方法来进行解码
Object result = decode(response);
shouldClose = closeAfterDecode;
return result;
}
} else if (decode404 && response.status() == 404 && void.class != metadata.returnType()) {
Object result = decode(response);
shouldClose = closeAfterDecode;
return result;
} else {
// 调用ErrorDecoder进行错误解码
throw errorDecoder.decode(metadata.configKey(), response);
}
} catch (IOException e) {
if (logLevel != Logger.Level.NONE) {
logger.logIOException(metadata.configKey(), logLevel, e, elapsedTime);
}
throw errorReading(request, response, e);
} finally {
if (shouldClose) {
ensureClosed(response.body());
}
}
}

欢迎关注我的其它发布渠道