2121
2222import feign .InvocationHandlerFactory .MethodHandler ;
2323import feign .Request .Options ;
24+ import feign .interceptor .Invocation ;
25+ import feign .interceptor .MethodInterceptor ;
2426import java .io .IOException ;
2527import java .util .List ;
2628import java .util .Optional ;
@@ -56,23 +58,39 @@ private AsynchronousMethodHandler(
5658 public Object invoke (Object [] argv ) throws Throwable {
5759 RequestTemplate template = methodHandlerConfiguration .getBuildTemplateFromArgs ().create (argv );
5860 Options options = findOptions (argv );
59- Retryer retryer = this .methodHandlerConfiguration .getRetryer ().clone ();
60- try {
61- if (methodInfo .isAsyncReturnType ()) {
62- return executeAndDecode (template , options , retryer );
63- } else {
64- return executeAndDecode (template , options , retryer ).join ();
65- }
66- } catch (CompletionException e ) {
67- throw e .getCause ();
68- }
61+ Invocation invocation =
62+ new Invocation (
63+ methodHandlerConfiguration .getTarget (),
64+ methodHandlerConfiguration .getMetadata (),
65+ template ,
66+ argv );
67+
68+ MethodInterceptor .Chain endOfChain =
69+ inv -> {
70+ Retryer retryer = this .methodHandlerConfiguration .getRetryer ().clone ();
71+ try {
72+ if (methodInfo .isAsyncReturnType ()) {
73+ return executeAndDecode (inv , options , retryer );
74+ } else {
75+ return executeAndDecode (inv , options , retryer ).join ();
76+ }
77+ } catch (CompletionException e ) {
78+ throw e .getCause ();
79+ }
80+ };
81+ MethodInterceptor .Chain chain =
82+ methodHandlerConfiguration .getMethodInterceptors ().stream ()
83+ .reduce (MethodInterceptor ::andThen )
84+ .map (interceptor -> interceptor .apply (endOfChain ))
85+ .orElse (endOfChain );
86+ return chain .next (invocation );
6987 }
7088
7189 private CompletableFuture <Object > executeAndDecode (
72- RequestTemplate template , Options options , Retryer retryer ) {
90+ Invocation invocation , Options options , Retryer retryer ) {
7391 CancellableFuture <Object > resultFuture = new CancellableFuture <>();
7492
75- executeAndDecode (template , options )
93+ executeAndDecode (invocation , options )
7694 .whenComplete (
7795 (response , throwable ) -> {
7896 if (throwable != null ) {
@@ -85,7 +103,7 @@ private CompletableFuture<Object> executeAndDecode(
85103 methodHandlerConfiguration .getLogLevel ());
86104 }
87105
88- resultFuture .setInner (executeAndDecode (template , options , retryer ));
106+ resultFuture .setInner (executeAndDecode (invocation , options , retryer ));
89107 }
90108 } else {
91109 resultFuture .complete (response );
@@ -154,7 +172,8 @@ private boolean shouldRetry(
154172 }
155173 }
156174
157- private CompletableFuture <Object > executeAndDecode (RequestTemplate template , Options options ) {
175+ private CompletableFuture <Object > executeAndDecode (Invocation invocation , Options options ) {
176+ RequestTemplate template = invocation .requestTemplate ();
158177 Request request = targetRequest (template );
159178
160179 if (methodHandlerConfiguration .getLogLevel () != Logger .Level .NONE ) {
@@ -170,9 +189,12 @@ private CompletableFuture<Object> executeAndDecode(RequestTemplate template, Opt
170189 return client
171190 .execute (request , options , Optional .ofNullable (requestContext ))
172191 .thenApply (
173- response ->
174- // TODO: remove in Feign 12
175- ensureRequestIsSet (response , template , request ))
192+ response -> {
193+ // TODO: remove in Feign 12
194+ Response withRequest = ensureRequestIsSet (response , template , request );
195+ invocation .response (withRequest );
196+ return withRequest ;
197+ })
176198 .exceptionally (
177199 throwable -> {
178200 CompletionException completionException =
@@ -237,6 +259,7 @@ static class Factory<C> implements MethodHandler.Factory<C> {
237259 private final AsyncClient <C > client ;
238260 private final Retryer retryer ;
239261 private final List <RequestInterceptor > requestInterceptors ;
262+ private final List <MethodInterceptor > methodInterceptors ;
240263 private final AsyncResponseHandler responseHandler ;
241264 private final Logger logger ;
242265 private final Logger .Level logLevel ;
@@ -249,6 +272,7 @@ static class Factory<C> implements MethodHandler.Factory<C> {
249272 AsyncClient <C > client ,
250273 Retryer retryer ,
251274 List <RequestInterceptor > requestInterceptors ,
275+ List <MethodInterceptor > methodInterceptors ,
252276 AsyncResponseHandler responseHandler ,
253277 Logger logger ,
254278 Logger .Level logLevel ,
@@ -259,6 +283,7 @@ static class Factory<C> implements MethodHandler.Factory<C> {
259283 this .client = checkNotNull (client , "client" );
260284 this .retryer = checkNotNull (retryer , "retryer" );
261285 this .requestInterceptors = checkNotNull (requestInterceptors , "requestInterceptors" );
286+ this .methodInterceptors = checkNotNull (methodInterceptors , "methodInterceptors" );
262287 this .responseHandler = responseHandler ;
263288 this .logger = checkNotNull (logger , "logger" );
264289 this .logLevel = checkNotNull (logLevel , "logLevel" );
@@ -280,6 +305,7 @@ public MethodHandler create(Target<?> target, MethodMetadata metadata, C request
280305 target ,
281306 retryer ,
282307 requestInterceptors ,
308+ methodInterceptors ,
283309 logger ,
284310 logLevel ,
285311 buildTemplateFromArgs ,
0 commit comments