diff --git a/extras/retrofit2/pom.xml b/extras/retrofit2/pom.xml
index 2271afe0ea..317e96b28a 100644
--- a/extras/retrofit2/pom.xml
+++ b/extras/retrofit2/pom.xml
@@ -13,7 +13,7 @@
 
   
     2.5.0
-    1.16.20
+    1.18.6
   
 
   
diff --git a/extras/retrofit2/src/main/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCall.java b/extras/retrofit2/src/main/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCall.java
index 9197351233..39107ce02a 100644
--- a/extras/retrofit2/src/main/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCall.java
+++ b/extras/retrofit2/src/main/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCall.java
@@ -30,6 +30,7 @@
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.atomic.AtomicReference;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 /**
  * {@link AsyncHttpClient} Retrofit2 {@link okhttp3.Call}
@@ -48,6 +49,7 @@ class AsyncHttpClientCall implements Cloneable, okhttp3.Call {
   public static final long DEFAULT_EXECUTE_TIMEOUT_MILLIS = 30_000;
 
   private static final ResponseBody EMPTY_BODY = ResponseBody.create(null, "");
+
   /**
    * Tells whether call has been executed.
    *
@@ -55,37 +57,44 @@ class AsyncHttpClientCall implements Cloneable, okhttp3.Call {
    * @see #isCanceled()
    */
   private final AtomicReference> futureRef = new AtomicReference<>();
+
   /**
-   * HttpClient instance.
+   * {@link AsyncHttpClient} supplier
    */
   @NonNull
-  AsyncHttpClient httpClient;
+  Supplier httpClientSupplier;
+
   /**
    * {@link #execute()} response timeout in milliseconds.
    */
   @Builder.Default
   long executeTimeoutMillis = DEFAULT_EXECUTE_TIMEOUT_MILLIS;
+
   /**
    * Retrofit request.
    */
   @NonNull
   @Getter(AccessLevel.NONE)
   Request request;
+
   /**
    * List of consumers that get called just before actual async-http-client request is being built.
    */
   @Singular("requestCustomizer")
   List> requestCustomizers;
+
   /**
    * List of consumers that get called just before actual HTTP request is being fired.
    */
   @Singular("onRequestStart")
   List> onRequestStart;
+
   /**
    * List of consumers that get called when HTTP request finishes with an exception.
    */
   @Singular("onRequestFailure")
   List> onRequestFailure;
+
   /**
    * List of consumers that get called when HTTP request finishes successfully.
    */
@@ -236,6 +245,20 @@ public Response onCompleted(org.asynchttpclient.Response response) {
     return future;
   }
 
+  /**
+   * Returns HTTP client.
+   *
+   * @return http client
+   * @throws IllegalArgumentException if {@link #httpClientSupplier} returned {@code null}.
+   */
+  protected AsyncHttpClient getHttpClient() {
+    val httpClient = httpClientSupplier.get();
+    if (httpClient == null) {
+      throw new IllegalStateException("Async HTTP client instance supplier " + httpClientSupplier + " returned null.");
+    }
+    return httpClient;
+  }
+
   /**
    * Converts async-http-client response to okhttp response.
    *
diff --git a/extras/retrofit2/src/main/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallFactory.java b/extras/retrofit2/src/main/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallFactory.java
index 85139718d5..0077cd32e3 100644
--- a/extras/retrofit2/src/main/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallFactory.java
+++ b/extras/retrofit2/src/main/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallFactory.java
@@ -18,29 +18,22 @@
 import org.asynchttpclient.AsyncHttpClient;
 
 import java.util.List;
-import java.util.Optional;
 import java.util.function.Consumer;
 import java.util.function.Supplier;
 
 import static org.asynchttpclient.extras.retrofit.AsyncHttpClientCall.runConsumers;
 
 /**
- * {@link AsyncHttpClient} implementation of Retrofit2 {@link Call.Factory}
+ * {@link AsyncHttpClient} implementation of Retrofit2
+ * {@link Call.Factory}.
  */
 @Value
 @Builder(toBuilder = true)
 public class AsyncHttpClientCallFactory implements Call.Factory {
   /**
-   * {@link AsyncHttpClient} in use.
-   *
-   * @see #httpClientSupplier
-   */
-  @Getter(AccessLevel.NONE)
-  AsyncHttpClient httpClient;
-
-  /**
-   * Supplier of {@link AsyncHttpClient}, takes precedence over {@link #httpClient}.
+   * Supplier of {@link AsyncHttpClient}.
    */
+  @NonNull
   @Getter(AccessLevel.NONE)
   Supplier httpClientSupplier;
 
@@ -48,12 +41,13 @@ public class AsyncHttpClientCallFactory implements Call.Factory {
    * List of {@link Call} builder customizers that are invoked just before creating it.
    */
   @Singular("callCustomizer")
+  @Getter(AccessLevel.PACKAGE)
   List> callCustomizers;
 
   @Override
   public Call newCall(Request request) {
     val callBuilder = AsyncHttpClientCall.builder()
-            .httpClient(httpClient)
+            .httpClientSupplier(httpClientSupplier)
             .request(request);
 
     // customize builder before creating a call
@@ -64,15 +58,33 @@ public Call newCall(Request request) {
   }
 
   /**
-   * {@link AsyncHttpClient} in use by this factory.
+   * Returns {@link AsyncHttpClient} from {@link #httpClientSupplier}.
    *
-   * @return
+   * @return http client.
    */
-  public AsyncHttpClient getHttpClient() {
-    return Optional.ofNullable(httpClientSupplier)
-            .map(Supplier::get)
-            .map(Optional::of)
-            .orElseGet(() -> Optional.ofNullable(httpClient))
-            .orElseThrow(() -> new IllegalStateException("HTTP client is not set."));
+  AsyncHttpClient getHttpClient() {
+    return httpClientSupplier.get();
+  }
+
+  /**
+   * Builder for {@link AsyncHttpClientCallFactory}.
+   */
+  public static class AsyncHttpClientCallFactoryBuilder {
+    /**
+     * {@link AsyncHttpClient} supplier that returns http client to be used to execute HTTP requests.
+     */
+    private Supplier httpClientSupplier;
+
+    /**
+     * Sets concrete http client to be used by the factory to execute HTTP requests. Invocation of this method
+     * overrides any previous http client supplier set by {@link #httpClientSupplier(Supplier)}!
+     *
+     * @param httpClient http client
+     * @return reference to itself.
+     * @see #httpClientSupplier(Supplier)
+     */
+    public AsyncHttpClientCallFactoryBuilder httpClient(@NonNull AsyncHttpClient httpClient) {
+      return httpClientSupplier(() -> httpClient);
+    }
   }
 }
\ No newline at end of file
diff --git a/extras/retrofit2/src/test/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallFactoryTest.java b/extras/retrofit2/src/test/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallFactoryTest.java
index cec3ece12b..864931a583 100644
--- a/extras/retrofit2/src/test/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallFactoryTest.java
+++ b/extras/retrofit2/src/test/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallFactoryTest.java
@@ -14,23 +14,34 @@
 
 import lombok.extern.slf4j.Slf4j;
 import lombok.val;
+import okhttp3.MediaType;
 import okhttp3.Request;
+import okhttp3.RequestBody;
 import okhttp3.Response;
 import org.asynchttpclient.AsyncHttpClient;
 import org.asynchttpclient.RequestBuilder;
 import org.testng.annotations.Test;
 
+import java.util.Objects;
 import java.util.UUID;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
 
-import static org.asynchttpclient.extras.retrofit.AsyncHttpClientCallTest.REQUEST;
 import static org.asynchttpclient.extras.retrofit.AsyncHttpClientCallTest.createConsumer;
 import static org.mockito.Mockito.mock;
 import static org.testng.Assert.*;
 
 @Slf4j
 public class AsyncHttpClientCallFactoryTest {
+  private static final MediaType MEDIA_TYPE = MediaType.parse("application/json");
+  private static final String JSON_BODY = "{\"foo\": \"bar\"}";
+  private static final RequestBody BODY = RequestBody.create(MEDIA_TYPE, JSON_BODY);
+  private static final String URL = "http://localhost:11000/foo/bar?a=b&c=d";
+  private static final Request REQUEST = new Request.Builder()
+          .post(BODY)
+          .addHeader("X-Foo", "Bar")
+          .url(URL)
+          .build();
   @Test
   void newCallShouldProduceExpectedResult() {
     // given
@@ -152,7 +163,8 @@ void shouldApplyAllConsumersToCallBeingConstructed() {
     assertTrue(call.getRequestCustomizers().size() == 2);
   }
 
-  @Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = "HTTP client is not set.")
+  @Test(expectedExceptions = NullPointerException.class,
+          expectedExceptionsMessageRegExp = "httpClientSupplier is marked @NonNull but is null")
   void shouldThrowISEIfHttpClientIsNotDefined() {
     // given
     val factory = AsyncHttpClientCallFactory.builder()
@@ -168,17 +180,23 @@ void shouldThrowISEIfHttpClientIsNotDefined() {
   @Test
   void shouldUseHttpClientInstanceIfSupplierIsNotAvailable() {
     // given
-    val httpClientA = mock(AsyncHttpClient.class);
+    val httpClient = mock(AsyncHttpClient.class);
 
     val factory = AsyncHttpClientCallFactory.builder()
-            .httpClient(httpClientA)
+            .httpClient(httpClient)
             .build();
 
     // when
     val usedHttpClient = factory.getHttpClient();
 
     // then
-    assertTrue(usedHttpClient == httpClientA);
+    assertTrue(usedHttpClient == httpClient);
+
+    // when
+    val call = (AsyncHttpClientCall) factory.newCall(REQUEST);
+
+    // then: call should contain correct http client
+    assertTrue(call.getHttpClient()== httpClient);
   }
 
   @Test
@@ -197,5 +215,12 @@ void shouldPreferHttpClientSupplierOverHttpClient() {
 
     // then
     assertTrue(usedHttpClient == httpClientB);
+
+    // when: try to create new call
+    val call = (AsyncHttpClientCall) factory.newCall(REQUEST);
+
+    // then: call should contain correct http client
+    assertNotNull(call);
+    assertTrue(call.getHttpClient() == httpClientB);
   }
 }
diff --git a/extras/retrofit2/src/test/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallTest.java b/extras/retrofit2/src/test/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallTest.java
index 84ed4ddf47..ab908730af 100644
--- a/extras/retrofit2/src/test/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallTest.java
+++ b/extras/retrofit2/src/test/java/org/asynchttpclient/extras/retrofit/AsyncHttpClientCallTest.java
@@ -24,6 +24,7 @@
 import org.asynchttpclient.Response;
 import org.mockito.ArgumentCaptor;
 import org.testng.Assert;
+import org.testng.annotations.BeforeMethod;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
@@ -35,10 +36,11 @@
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.function.Consumer;
+import java.util.function.Supplier;
 
 import static org.asynchttpclient.extras.retrofit.AsyncHttpClientCall.runConsumer;
 import static org.asynchttpclient.extras.retrofit.AsyncHttpClientCall.runConsumers;
-import static org.mockito.Matchers.any;
+import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.*;
 import static org.testng.Assert.assertEquals;
 import static org.testng.Assert.assertNotEquals;
@@ -47,6 +49,14 @@
 public class AsyncHttpClientCallTest {
     static final Request REQUEST = new Request.Builder().url("http://www.google.com/").build();
 
+    private AsyncHttpClient httpClient;
+    private Supplier httpClientSupplier = () -> httpClient;
+
+    @BeforeMethod
+    void setup() {
+      this.httpClient = mock(AsyncHttpClient.class);
+    }
+
     @Test(expectedExceptions = NullPointerException.class, dataProvider = "first")
     void builderShouldThrowInCaseOfMissingProperties(AsyncHttpClientCall.AsyncHttpClientCallBuilder builder) {
         builder.build();
@@ -54,12 +64,10 @@ void builderShouldThrowInCaseOfMissingProperties(AsyncHttpClientCall.AsyncHttpCl
 
     @DataProvider(name = "first")
     Object[][] dataProviderFirst() {
-        val httpClient = mock(AsyncHttpClient.class);
-
         return new Object[][]{
                 {AsyncHttpClientCall.builder()},
                 {AsyncHttpClientCall.builder().request(REQUEST)},
-                {AsyncHttpClientCall.builder().httpClient(httpClient)}
+                {AsyncHttpClientCall.builder().httpClientSupplier(httpClientSupplier)}
         };
     }
 
@@ -77,7 +85,7 @@ void shouldInvokeConsumersOnEachExecution(Consumer> ha
         val numRequestCustomizer = new AtomicInteger();
 
         // prepare http client mock
-        val httpClient = mock(AsyncHttpClient.class);
+        this.httpClient = mock(AsyncHttpClient.class);
 
         val mockRequest = mock(org.asynchttpclient.Request.class);
         when(mockRequest.getHeaders()).thenReturn(EmptyHttpHeaders.INSTANCE);
@@ -94,7 +102,7 @@ void shouldInvokeConsumersOnEachExecution(Consumer> ha
 
         // create call instance
         val call = AsyncHttpClientCall.builder()
-                .httpClient(httpClient)
+                .httpClientSupplier(httpClientSupplier)
                 .request(REQUEST)
                 .onRequestStart(e -> numStarted.incrementAndGet())
                 .onRequestFailure(t -> numFailed.incrementAndGet())
@@ -163,7 +171,7 @@ Object[][] dataProviderSecond() {
     void toIOExceptionShouldProduceExpectedResult(Throwable exception) {
         // given
         val call = AsyncHttpClientCall.builder()
-                .httpClient(mock(AsyncHttpClient.class))
+                .httpClientSupplier(httpClientSupplier)
                 .request(REQUEST)
                 .build();
 
@@ -295,6 +303,18 @@ public void bodyIsNotNullInResponse() throws Exception {
         assertNotEquals(response.body(), null);
     }
 
+    @Test(expectedExceptions = IllegalStateException.class, expectedExceptionsMessageRegExp = ".*returned null.")
+    void getHttpClientShouldThrowISEIfSupplierReturnsNull() {
+      // given:
+      val call = AsyncHttpClientCall.builder()
+              .httpClientSupplier(() -> null)
+              .request(requestWithBody())
+              .build();
+
+      // when: should throw ISE
+      call.getHttpClient();
+    }
+
     private void givenResponseIsProduced(AsyncHttpClient client, Response response) {
         when(client.executeRequest(any(org.asynchttpclient.Request.class), any())).thenAnswer(invocation -> {
             AsyncCompletionHandler handler = invocation.getArgument(1);
@@ -304,9 +324,11 @@ private void givenResponseIsProduced(AsyncHttpClient client, Response response)
     }
 
     private okhttp3.Response whenRequestIsMade(AsyncHttpClient client, Request request) throws IOException {
-        AsyncHttpClientCall call = AsyncHttpClientCall.builder().httpClient(client).request(request).build();
-
-        return call.execute();
+        return AsyncHttpClientCall.builder()
+                .httpClientSupplier(() -> client)
+                .request(request)
+                .build()
+                .execute();
     }
 
     private Request requestWithBody() {